[Silence]
>> Chris Gerber: Welcome.
My name is Chris Gerber and this is CS 76.
Tonight we'll be doing Lab 2.
We're going to start off with a walkthrough of the next project
which is Evil Hangman.
So we'll start out with an overview of the project.
We're going to talk about the equivalence classes
which are sort of key to how Evil Hangman is going to work.
We'll talk about setting up the project, how we're going
to get input in the application, how we can use property lists
within the project and finish up with just a little bit
about how you can store setting in your application.
So first of all, Evil Hangman.
The goal of the game is to try to make the player lose
and the way we're going to do
that is we're just going to cheat.
How we're going to cheat is after each guess we're going
to select the longest possible list of words
that is still available after that guess.
This will make more sense as we get into it.
So let's say we start with a very short list.
We've got these seven items.
I've got cat, cot, cow, dog, dot, tag and tot.
So I have a minimum number of letters.
We've only got maybe a half dozen letters here to work with.
What are we going to do?
So the player is going to come up and guess a letter.
So let's say they've guessed the letter T. For each
of the words we can then map what that guess would do
to what the board would look like at that time.
So if the word was cat and they guessed T they would have gotten
the T in the third location
and the first two would still be blank.
If the word was actually cow
and they had guessed T they wouldn't have any letters
matching yet.
If the word was actually tot they would get T-T.
So you get this idea of if you'd played hangman before
as you guess letters you fill in the blanks, so the possibilities
after all this are we could end up with -- T.
We could end up with -- - .
We could end up with T-- or we could end up with T-T.
So there's really only four possible outcomes at this point
in the game no matter what the words were to start with.
Moving from there we now have these four different classes
and we can look at them.
The words cat, cot and dot have all mapped to -- T.
So there are three cases that we can get to in that case.
If it was cow or dog it would have matched to -- - .
So there are only two possibilities in that case.
So obviously what we want to do
at this point is pick what gives us the most opportunities.
So if we look at this choice we've got three possible words
still in the list so even though here we might not be showing
that any letter has matched it's not as strategic a location
for us to end up so what we'd rather do is show the user --
T and still have three possible outcomes to work with.
Does this basic idea sort of make sense?
So then we can continue.
We've got this new list and the person guesses the letter C.
We've got these three conditions they map out to C-T or -- T.
Repeat the process.
We see that there are now two cases for C-T
and that is still our best case situation,
so we'll pick that and continue on.
If they guess A we get to a special case now.
Each one is going to map to one condition but we definitely want
to pick the best equivalence class for us which is cot
because the user has not won.
So we are going to hit situations
where potentially the number of words in each list is the same.
If there's no clear outcome we should just do something sort
of random.
If there is a clear outcome we should try
to make the player lose.
This is still following?
It's still good?
All right, so how do we actually do this?
I mean, the idea makes sense.
You can get a little sense of how you would play this
with your friends if you were working on paper.
If we go out to Wikipedia we'll see this, equivalence classes.
"The equivalence class of an element A is denoted, bracket A,
may be defined as the set of elements
that are related to, A by tilde."
This does not tell me a whole lot.
What this basically translates to is you should define a set
of words sharing a given letter at a given location
and the other thing that comes
out of it actually is order matters.
So -- T is treated differently than T-- .
So what would this look like in code?
It would have been great
but X code has no idea what NS equivalence class is.
We just can't get it for free in this case, so we have to think
about how we would actually implement this.
So we've got a few options.
We've heard about some of these classes and type, classes
and class, so we have things like NS mutable dictionaries,
NS mutable arrays, there's also something called an NS
mutable set.
As you remember the dictionaries map keys to values.
An array is just a list of items but they're in a specific order.
A set is different than those two.
It's more like an array in that it's a list of items
but the order of the items is not preserved.
It's just a collection of items.
So if we think about what we're going
to do here we can start mapping this out in pseudocode.
For each word in the set we need
to determine what the equivalence class is
for the word and then we can add that word
to that equivalence class.
So if the word was cat we've come up and guessed T we come
to the equivalence class -- T.
We can then say for the equivalence class name --
T I can add cat to that list.
When we get done we're going
to determine the largest equivalence class.
We can remove all the other words because they're
out of play at this point and then we have
to update the user interface
so the player knows what's going on in the game.
I think I've already covered all
that so we're going to skip that.
So what should we be thinking
about as we're implementing this?
So time and space are things we should always about thinking
about when we're writing our code.
In this case when we think about time we have to think
about iterating over lists.
That's going to be an a very slow process.
If we can do something
that actually uses an index it will help the performance a lot,
so we should look into the fact that we could index into arrays
and dictionaries very quickly so that might drive your decisions.
Another thing to think about
and this will make more sense later I would consider
that loading plists from storage is actually a slow process.
If we can keep stuff in memory that is overall going
to help performance, of course then we have to start thinking
about our space considerations.
So words.plist is a pretty big file.
The file we're going to give you is just shy
of 250 thousand words.
It's still just text.
It's not huge but we're dealing with a device
that actually doesn't have a lot of storage.
So that's something to think about.
We'll want to keep our data structures as small as possible
and we're also going to have to keep in mind that we don't want
to keep things in memory longer than needed so we'll have
to trade that off versus loaded from storage is slow.
How long should we keep things in memory?
You'll remember that when memory gets low IOS will actually warn
us so perhaps we can keep things in memory for a while,
be optimistic but if we're told that we have to give back memory
that might be the time that we actually have to make a change
and then keep track of what state we're in.
So just a few things for you to ponder as you start working
through this exercise.
One thing that you should keep
in mind though is this quote from Donald Knuth.
If you don't know who he is you should look him up.
He's a good guy.
He said, "We should forget about small efficiencies,
say about 97 percent of the time:
Premature optimization is the root of all evil.
Yet we should not pass up our opportunities
in that critical 3 percent."
So certainly we want to do what we can to squeeze
out every last bit of memory
but that should not be your first goal.
Your first goal should be getting things into memory,
getting things basically working
and if you can start tweaking things afterwards that's great
or if you start seeing
that things are particularly slow then it's time
to start thinking about things.
You have question?
>> I just want [inaudible] for a second, particularly
if you could go back to that last slide.
I'm not really sure I understand.
We're iterating over all of the words in the collection
and determining an equivalence of each of them why is
that process slower than indexing arrays
or dictionaries assuming
that they are all consecutively arranged [inaudible]
>> Chris Gerber: Okay, so the question is
around why is iterating over the lists going to be slower
than indexing into the arrays the way we're working?
So one thing you might want to think
about out there is we've got 250 thousand words approximately.
All those words are different lengths and if you know
that the length of the word is for example,
eight characters you might only want to work with a subset
of the list that is only eight character words and you can have
that indexed out to a chunk of memories
so you're only iterating over that subset and then
as equivalence classes get thrown
out you can shift yourself down to a smaller list of words
so you're not iterating over 250 thousand every time
or perhaps ten thousand then five thousand then two thousand.
That's sort of more of where I was going there.
Does that make is sense?
>> Yeah, you'll be chunking around with more
because you would be only picking out words--
>> Chris Gerber: -- of certain length
or have already been excluded.
Yeah. All right?
Yeah, another question?
>> [Inaudible question]
>> Chris Gerber: Yeah, so the question is
around setting the length of the word.
If you look at the specification,
what we've specified is we'll be using utility application
which sort of has a front side and a back side.
The front side will be the playing of the game.
The back side will be for configuring the game and one
of the things you'll be implementing is a slider
that sets the length of the word that the user will be playing
with at that time and every time they restart the game
until they change the length of the word it will continue
to use that word length.
So we'll be setting that as part of our settings
which might be preloaded from disk,
persisted for the next time they play, etcetera.
Things to think about there.
Does that make sense?
Okay and did you have a question?
>> Does it matter how long we set the amount it can change to,
five to ten letters?
>> Chris Gerber: So the question is does it matter how long,
what the choices are for length of word?
And what we'll ask you to do is assume that it is based
on what you find in the file.
So as you first load the file you'll want to look through
and figure out what the shortest and longest words are
in the file and that will be the size of your slider.
Another question.
>> [Inaudible question]
>> Chris Gerber: So the question is as we first load a file
into memory or as we first look at the plist we need
to load the entire thing into memory and is that a concern?
That is an unfortunate situation that we have to deal with.
You will have to load everything into memory once and then
from there you can decide how much you are going to retain
in memory as the application runs.
>> Are we going to have a choice as to data structure
that we are going use to store the information
in memory like [inaudible]
>> Chris Gerber: The question is
around what data structure we're going to use to store this
in memory and that is completely open to your interpretation
of the problem and how you actually want to implement it.
You should probably stick with some of the common built
in data types but it's up to you
to determine what you want to do.
>> And as a side note you don't have to load it
in [inaudible] plists.
You're free to pre-process it in whichever ways you want
but any [inaudible] of those words support it.
>> Chris Gerber: That was a great point
if the cameras didn't pick it up.
You don't need to load plist in your application.
You can pre-process the file and do something else to deal
with that so I think the specification actually mentions
parenthetically that you could use something
like a SQL-like database
or you could somehow otherwise pre-process the file
so you're using smaller subsets as you were.
Another question?
>> [Inaudible question]
>> Chris Gerber: So the question is around the strict definition
of equivalence classes being symmetric, transitive,
I missed the other one.
>> Reflexive?
>> Chris Gerber: Reflexive.
I honestly don't have a good answer on that one.
Anything else?
All right, so just to summarize, at every point you want
to leave yourself the most number of options that you can.
If at all possible you don't want the player to win
and if you have the opportunity you should think
about how you might optimize our very simple algorithm further.
So getting down to real details, how do we get started?
We're going to be using a utility application
and that's one of the standard templates
that you'll see in Xcode.
It contains two controllers, a MainViewController
and a FlipsideViewController.
Typically, the Flipside Controller is used
for storing configurations, storing settings.
For those that have played with an iPhone you can pick
up something like the Apple Weather App but I can also
on the fly, too many windows.
I know what happened.
I have to exit my show first.
All right, now I've got code all over the place.
Get that out of the way, get this out of the way.
All right, oh, I don't have it there.
After all that I can't even show you what I was going
to show you.
That's what-- now I've lost PowerPoint.
All right, so for now I will assume that you can picture sort
of what the application looks like
and we'll move forward from there.
All right, with the utility application one
of the things we'll have to use is this idea
of delegates and protocols.
So what a delegate is it identifies an object
that will handle an action on your behalf rather
than you handling the action.
And where we're going to see this
in this particular case is the FlipsideViewController requires
a delegate which is the MainViewController
and this allows the MainViewController
to have a piece of code that runs that is passed to it
from the FlipsideViewController.
So any changes you make
on the Flipside can be communicated back
to the MainViewController.
So you've change the slider.
It's essentially got call back as we saw on Java script
where it can call back to MainViewController
and say "Hey, this was updated."
To use a delegate you have to implement a protocol.
In this case it will be a FlipsideViewController protocol
that it knows what to do and the protocol essentially just
guarantees that the methods you specify will be implemented.
The protocol itself will look something like this.
You'll have at protocol, some name for the protocol.
You can have a number of methods that could either be voids,
they could return values, they could be passed in values
and then at end the at the end of the method.
All right, so let's see if we can actually take a look
at the utility application.
So I'm going to go from Xcode, File, New Project.
Utility application can be found under IOS application.
It'll ask you for a product name.
So I can give it a name.
Your organization can be anything.
I've just been using my name.
I believe the spec asks you to edu.Harvard
as your company identifier.
We don't need to use class prefix at this time
and for this I'm just going to use iPhone.
You can also specify iPad or Universal.
We're not going to use story boards at this time
but we will talk about them a bit later tonight.
We don't need to use core data at this time.
Core data is essentially a back in data store that you can use
with your applications.
We are going to use automatic reference counting
and for tonight I'm not going to include any unit tests.
I'll just assume I know what I'm going
and my code is going to run.
It'll ask you for a place to save your code
and you can create a local get repository or not.
I personally like to because I use get all day
and am very familiar with the source control
but it's not strictly necessary for what we're doing
and you can hit create.
So that will give us our new application.
As we mentioned there's the MainViewController.
There's the FlipsideViewController.
Each of those is also going to have a NIB file
so this should look vaguely familiar from lecture.
If you look
at the MainViewController you'll see it's not very complicated.
There is one little button down here.
Let's see if I can, let me put my simulator--
[On Screen Activity Being Performed]
So I don't have the fancy border on here
but you can see it's the same window.
It's got the information button.
As we mentioned, all this is going
to do is flip to the other side.
This is where we would see things like settings.
We hit done.
We flip back to the first side.
To round that out you'll see the FlipsideViewController has the
done button entitled that we saw and you can look
through the actual implementations.
There's not a ton here.
Things like view did load, view did receive memory warning,
we've seen before and obviously they're blank
so they could be deleted at this time.
If we actually look at the header first we'll see
that there is a FlipsideViewController delegate
as we mentioned so that we can do something
on behalf of the flip side.
You'll see that's actually implemented here.
The method that's promised
through that protocol is a FlipsideViewController did
finish method.
Yeah, sorry.
Which one is it?
Control, Option, INT.
Ah, there we go.
Of course, my window has gone so far over--
now I can't-- there we go.
So FlipsideViewController did finish.
It's going to take the controller as it's argument.
In this case all it's going to do is do an animated close
but this is our opportunity to have access to the variables
that are in scope of the FlipsideViewController
and do whatever we need to do.
So if there was a slider that had a value of ten we could take
that ten and change some variable
in our local scope as well.
Does that basic idea make sense?
Okay and the FlipsideViewController is very
straight forward.
We've got the actual protocol here that we implemented
which is the FlipsideViewController
did finish.
This is the promise that we made
when we said we would implement this delegate.
And the only actual line of curve that we might care
about here is that when we click the done button the
FlipsideViewController says it is going to finish.
All right, that's all I wanted to cover there.
All right, so how are we actually going
to get input in the application?
So ideally we want to see keyboard popped up.
We want to hit a letter.
It's going to process the letter, think about it.
The way to get input in an IOS application is
to use a UI text field.
UI text field itself is great
if you're just doing traditional stuff but if you want
to do more you can use a UI text field delegate
and that gives you additional functionality.
This also lets you do things
like actually make the text field hidden
which is probably what we'd like in this application.
We want to listen to the keyboard.
We want to respond to the key presses
but we don't want necessarily that text appearing
on the screen in a box somewhere.
We want to process it in a more intelligent manner.
So if we use this UI text field delegate we get some additional
methods that we can implement here.
We get text field should return.
This is what happens when someone hits the done button
on the keyboard and then we can do whatever is appropriate there
like perhaps hide the keyboard.
We've got text field should begin editing which is
when the user is about to edit text.
We can do whatever we need to set up our application then.
And there's a text field should end editing which is right
as the field is about to lose focus.
So now I've got a very quick demo
about what we can do with UI text field.
That is, this is it.
[On Screen Activity Being Performed]
All right, so I've made a simple utility application here.
I've got a text field and a label and that's it.
And what I'd like to have happen is
when the application launches first
of all it doesn't make much sense for the label
to actually say the word label so I want to change that.
The field for entering text is currently visible so I want
to hide that and then I have to deal
with how does this all get wired up?
So, let's look at that, the header first.
We're just off the screen.
All right, so you'll remember
from class we've got these two new things called IB outlets
and IB actions.
IB outlets let us control the properties for, sorry,
let us set properties from the UI
and IB actions let us allow us to respond
to actions occurring within the UI.
So I've got, as you've noticed the label and a text field.
In my application I've set up a label and a text field
and referred to them as text, label and keyboard.
And again just, you'll remember there's these little dots
that appear and I've prewired these up for us
and we'll see that in the UI side.
I've also created a new IB action here
for handling key presses.
So this is going the other way.
Rather than updating the UI I'm listening to the UI
and responding to what's happening.
We then switch over to the actual implementation.
We can see if we can get that a little more centered.
I've done a few things here.
So first when the application is first loading you'll remember we
see a view did load event occur.
So I've done a few things here.
I'm going to set the text label text to blank.
I can send a message to the edit field that I've called keyboard
and tell it to set its hidden property to yes.
Then the other thing I've done you'll remember
from class is I can do, send the keyboard
to become first responder message.
And what that message is going to do is basically tell it
that it is the primary control
and when a text field is the primary control the first thing
that it wants to do is display the keyboard.
So that's going to pop up the keyboard for me.
The other method he I implemented is this handle key
press method which you saw I created as an IB action.
And what I'm doing here is
when a UI text field has received key presses it appends
to a property called text.
So what I'm going to do is check the length of that text,
see if it has become greater than zero,
so something has been typed in.
If it is I'm going to change the text of the label
by setting the text to what the text of the label was,
create a new string by appending a string
and it scrolls off the side here.
Let me see if I can see it, yeah,
to whatever the keyboard text is.
So I'm taking what was
in the field I'm appending whatever the keyboard was
and then I'm going to set the value set in the edit field
to just blank, to zero it back out.
So this, every time it hears a key press it will take it,
append it to what was already in the field.
>> Chris, will we have access to these slides?
>> Chris Gerber: Yes, I will be--
the question was will we have access to these slides?
I will be uploading these slides and the source code
that I'm showing tonight to the CS 76 dot website.
It should be up before I go to bed
but that could be any time, hopefully, not five.
All right, the other thing I wanted to show is back in--
in the view controller you'll see
that I've wired the text label to file's owner
and it's not obvious that file's owner is on the screen.
I know what the dot, dot, dot means in this case.
That allows the controller to have right to that field
and for the text field I had to set two things.
Can I get them both to show?
Well, the first one is editing changed
so every time the contents
of the field are changing I am going
to tell the file's old owner to, it doesn't fully show
but call my handle key press method.
Let's see if I can get the other one for it.
The other one is down here.
Because I also need to be able to empty
out the field I've set the keyboard to be wired
up to file's owner as well and that allows me
to access those properties.
So putting it all together we can find our play button
and the application is gone off the bottom of the screen
but what we care about is at the top even though you can't see it
and the fact that you can't see it is a good thing, all right.
It doesn't show us the word label
which is what we wanted as a starting point.
It doesn't show us that edit field
but I can't see the keyboard.
I don't think it's running right.
Let's try this again.
I have a breakpoint in my application.
As you may remember if you put
in a breakpoint your code will stop running.
All right, so now if we continue, all right,
so the fields in the text are still going.
This time we actually got the keyboard
because the code is actually running at this point
as I type letters they do in fact make it to the label,
so sort of a blur, sort of a whirlwind.
You will have the code but does the basic idea make sense?
Does it all seem familiar based on what you saw in lecture?
All right.
>> If you could just show how to wire it out real fast
with the option key held down?
>> Chris Gerber: Yeah,
so the question is can we quickly redo the wiring just
to see that happen and we can absolutely do that.
All right, so let's first bring up the NIB file.
I'm going to make this window a little bit smaller
so we can see it.
There we go.
All right, so the easiest way to start doing this
and for the moment we don't need the items over here so let's get
that out of our way, give us a little more room to work with.
Remember, there's the assistant up here.
Show the assistant editor
which basically lets us put any two files side by side.
By default it will try to pick the most appropriate file
for you.
So in this case it did automatically detect that I want
to look at my header file which is good
because that is what I want it to.
Just for your own edification, if you click
on the filename there it will give you other logical choices.
You can also go back and instead
of automatic you can put any other file side by side
so you could go to manual and I could pick any file
to have two different things side by side.
But in this case this is what we want.
We want to see the view and we want to see our header file.
So I can come in here and that's what I wanted.
All right, so we can come in and delete the ones
that I had set up there.
All right so we've got the IB outlets for properties
and we've got the IB actions for methods.
Since we want to go from our code to the UI, I should be able
to option click from the text label to the text label
and we'll see that wired up text label to file's owner.
I can also do option click from UI text field to text field
and then I can do option click, sorry, control click
from the text field back to [inaudible].
So this one is actually different
because I actually want to use it editing changed so I can come
in here and wire that up to the method.
I actually don't know where the default is
so that would actually be interesting
if I had instead just gone there it would have chosen editing end
which is in fact not what I wanted in this case.
So something to be aware of if you--
>> So right now are you using option or control?
>> Chris Gerber: I'm using control at the moment.
All right, okay, let's go back to the slides here.
All right, so property lists.
Property lists are going to be very important
for what we're doing because the words we give you are
in a property list so that's a very important starting point
for you but basically property lists are just key value pairs.
You've got a way to look it up
and what the result is when you look it up.
It's stored in XML which you can just edit manually.
It's a standard XML file or you can use the plist editor
which gives you a little more of a gooey feel to it.
It might make it a little easier.
Frequently, property lists are used to store settings
and that is probably something
that will be useful for you as well.
You don't have to worry about a lot of this
but this is what a property list would actually look like.
The first few lines here just say
that essentially this is a property list.
We don't have to worry about that.
Where it gets more interesting is as we get in here.
So in this case in my property list happen to have a dictionary
that has a key and a string.
So this is my key value pair and it's standard XML
and you can go from there.
Interesting and useful to note is that NS dictionary
and NS array have methods to init with contents of file
to read in plist files and they also have methods
to write out plist files.
Also NS bundle has a method called path for resource of type
which lets you get to files in your local file system.
So obviously we're going to give you the plist file.
It has to get on the device and you have to have a way
to find it and read it.
So these are both going to be very important
for you should you be using plists [inaudible]
to do your work.
We can look at that quickly as well and we'll go back to Xcode
and currently this is right
in the same application I just did not show it to you yet
and I really haven't put much beyond it, much into it but it's
as good a chance for us to see what the [inaudible] looks
like as well since we haven't covered much of that.
There we go.
So you remember when I started I had a breakpoint in my code
that was causing us problems?
That was my breakpoint.
In my view did load function I added two commands.
I added a new variable file with path
that is going to use NS bundle.
It's going to use our main bundle which is predefined.
It's going to do path for resource.
We've got an NS string here called words and of type
of plist and this is basically going to say go
into your main bundle which is
where your application is storing its data.
Look for a file called words that is a words.plist file.
Once we've got that path built I'm using an NS mutable array
to store some words.
It's going to allocate that array and I'm just going
to use init with contents of file, file of path.
So this is essentially going to load my file.
Where we can see that is when we hit run we are going
to hit a breakpoint.
You'll see that file with path did in fact get set
to this long thing on my file system
but then the other thing you'll see is
that words is now an NS mutable array with 233 thousand objects
and I could actually start looking at what that looks like.
So it went by very quickly.
I just did a PO words which is off the screen,
sorry about that, and it doesn't want to go
and I can't go any higher.
All right, trust that this is PO words.
PO is short for print object.
At any point when you're at a breakpoint you can use PO
to print the contents of an object
in the output window here.
You can also use just straight P if it's not an object.
So remember things
like intra-traditional data types are not objects but things
like NS string, NS dictionary, etcetera are so you can use
that in your development as well.
And we're in the home stretch here.
So as you start thinking about settings you might also want
to look at this other object NS user defaults
and there are a number of methods here
that I think you'll find useful.
Register defaults lets you pre-store defaults
for your application but then you can use things like integer
for key to read an integer, set integer for key
to set an integer into these defaults,
string for keys, set object for key.
You remember you might think there should be set string
for key where a string is just an object,
it's an NS string so it's an object.
And there's plenty more but that's just one more hint
to help you work through your project here.
That is the end of my slides.
Are there any other questions for the walk
through of Evil Hangman?
Yes.
>> [Inaudible question]
>> Chris Gerber: So yeah, the question is around,
the spec says we should handle backgrounding the application
and basically what that means is if you are playing Evil Hangman
and either someone hits the home button or uses the task manager
to switch to another app or a phone call comes in
or whatever happens that interrupts the flow
of your application what should happen is the application will
move to the background.
It will be in a frozen state but when it comes back,
when Evil Hangman is run next it should pick
up where you left off.
So if you had guessed three letters and you were half way
through your game it should know you're in the middle
of that game and try to continue playing.
Certainly if you ran out of memory
and the application crashed or something
like that the state wouldn't come back
but in any case we can reserve state if we want it to do that.
>> [Inaudible question]
>> Chris Gerber: So the question asked was whether we have
to use NS user defaults to save the game state
when the application is backgrounded?
You do not need to do that.
NS user defaults should be used
for when you're first launching the application
or when you're starting a new game potentially
or when you are saving changes to your settings.
>> [Inaudible question]
>> Chris Gerber: So your question is then
when it backgrounds the state will be saved automatically?
And the answer to that would be yes.
>> [Inaudible question]
>> Chris Gerber: The question is can we say
that if you leave the game you lose?
That sounds very evil but that is not
in compliance with our spec. Yes.
>> [Inaudible question]
>> Chris Gerber: So the question is do we actually have
to draw a hangman?
You certainly have the option of drawing arms and legs, etcetera
but you can also just for example use a count
down that says "I have five guesses left."
Yes.
>> [Inaudible question]
>> Chris Gerber: So the question is the application needs
to handle low memory warnings by reloading views as needed.
So essentially if you were
on the MainViewController the FlipsideViewController can go
out of memory.
It can be discarded which means
that when it initializes you might need to reload
from NS user defaults to see what the settings are things
like that or if you are on the Flipside the state
of your screen might not be preserved.
You might have to go over to redraw the screen.
There are the callbacks are already there for things
such as view-- I'd have to look up the actual callback
that you'll see but there are callbacks that should show
up in the template applications.
They used to.
I don't know if they still do
that will let you detect those states
and determine what you need to do.
But we can look at that a little more when I can look it up.
>> [Inaudible question]
>> Chris Gerber: Yes, did receive memory warning.
>> Is it a smart idea to just use memory [inaudible]
>> Chris Gerber: So the question is is it all right
to keep using memory willy-nilly until you get a warning
or should you be proactive?
I would say the best practice would be to be proactive
and that you should certainly not just completely abuse memory
on the system to make things easy.
Yes.
>> [Inaudible question]
>> Chris Gerber: So the question is will we be using
story boards?
And that I believe is to the person's discretion.
Certainly what we presented
so far formally is not using story boards
but you are certainly welcome to use them in your app.
In this case it's pretty much as simple as checking the box
because if we're really just using the two flip sides
but if you wanted to change your segue or something
like that you can do that much easier
through the story boards I would think.
So yeah, it's fine to use them or fine to not.
>> Chris, I may say something really stupid
but the way I understand it is you load the whole dictionary
and you define the number of letters of the words.
Let's say three letters, okay?
So then the guy says okay, I have an E.
So then you eliminate all the words--
first of all you eliminate all the words don't have
three characters.
Then you eliminate all the words that have an E?
>> Chris Gerber: Not necessarily.
Yeah, so the question to summarize was
around the equivalence classes and also word blanks.
So for word blanks you can most likely very simply trim
down to just words of known length and that's fair
to describe the others rather quickly.
>> [Inaudible question]
>> Chris Gerber: Yes.
So the question is will there be a slider?
There will be a slider.
When you set that that will set what the state will be
for the next time you start the game.
So when the start new game button is hit you can then
or when the application very first launches you can load the
dictionary and potentially prune down to just words
of the currently configured blank.
The other part to your previous question was
around equivalence classes.
If the letter E was chosen you do not automatically discard all
the words that have the letter E in them.
You look for the group of words
that has the most available choices left.
So if that word happens to have an E in it
but it gives you a much longer list of possible choices
that could be a better choice
than discarding those that don't have Es.
All right, any other questions?
[Silence]