Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save maximveksler/8620861 to your computer and use it in GitHub Desktop.
Save maximveksler/8620861 to your computer and use it in GitHub Desktop.
Captions for Stanford CS193p Developing Applications for iOS Fall 2013-14, Lecture 4. Foundation and Attributed Strings. For more info visit http://maximveksler.github.io/CS193p/
00:05 >> Stanford University.
00:06 [ Pause ]
00:11 >> All right.
00:11 Well, welcome to lecture four, then, of CS 193P for fall of 2013/14 -- academic year 2013/14.
00:21 Today I'm going to do pretty much all slides.
00:24 I do have one brief time when we'll stop and do a little demo.
00:28 And then at the beginning of next lecture, I'll be doing a demo that pretty much demonstrates the vast majority of what I talk about in the slides today.
00:37 And remember, that's kind of how it's always going to go: I'll show it to you in slides, we'll talk about it, then I'll demo it to you.
00:42 Because when you see a demo, it all makes a lot more sense than if someone's just talking in an abstract conceptually about an API.
00:48 And then your homework is usually going to ask you to do this.
00:51 So it's, you know, you get a lot out of paying attention in the lectures because I'm pretty much going to give you hints and basically tell you a lot of how to do the homework -- at least from the iOS side of it.
01:01 I'm still going to ask you to do the thinking side of it, the designing side of it.
01:06 So today we're going to start off by talking about a little bit more miscellaneous Objective-C.
01:11 And then I'm going to go into talking about Foundation, which is this framework that has arrays, and dictionaries, and all that in it.
01:17 And we'll start to transition out of Foundation at the end of that and start talking about things like fonts and colors, which are obviously not in Foundation because Foundation is really not a UI-based thing; it's for building both your model, and your controller, and your view.
01:32 But it's, you know, a layer below the user interface layer.
01:36 So let's dive right in.
01:38 Let's talk about creating objects.
01:39 A few of these things are pretty obvious I hope, but I just want to put them on slides so that you have them in writing here.
01:45 You know that most of the time when we create objects in the heap, we do it with this alloc init business, right?
01:50 So sometimes the init is just init like NSMutableArray alloc init, and sometimes it's more complicated init like we had with our card matching game -- init with card count using deck -- so that you're used to that.
02:01 And you've also seen us create objects in the heap using class methods like string with format.
02:06 Remember, we did NSString, string with format.
02:08 And that's a class method, right?
02:09 Because it's open square bracket, name of a class, and then class method.
02:13 So it gets kind of two different ways you've seen already to create objects.
02:17 Sometimes for some methods, there's both an init and a class method.
02:23 So string with format is an example that there's alloc init with format and there's NSString, string with format.
02:29 They do exactly the same thing.
02:32 Both of them are there for kind of historical reasons.
02:35 Back before we had this automatic reference counting -- you know, the strong and weak thing -- you had to be much more explicit about things when you were going to, you know, reference them, and when they got dereferenced, and when you cleared them out of the heap, and all that stuff.
02:49 And one of the ways that was done was using these class methods to create the string in a way that it would get released in certain ways.
02:57 So all of that doesn't matter anymore.
02:59 So now we're kind of stuck with having both of these things.
03:02 It seems to me that iOS, the designers at Apple -- I don't work at Apple, by the way.
03:07 Some people have asked me if I work at Apple; I don't work at Apple.
03:09 So I'm just seeing iOS from the outside just like you are.
03:11 It looks to me like iOS people are moving towards alloc init, okay, and kind of away from the class methods.
03:19 Although I still see the class methods coming up in certain circumstances, too.
03:22 And there's probably some reasoning behind it.
03:24 I haven't seen it put in writing by Apple as to when they choose which, but you're certainly safe in this class until they start marketing some of these things as deprecated, like, don't use them anymore, to use either form, okay?
03:37 I tend to try to go for the alloc inits most of the time, unless there isn't an alloc init that does what I want; then I'll use a class method.
03:43 But there's other ways to create objects.
03:45 Okay? You can create objects by asking another object to create an object for you.
03:50 So that's like string by appending string.
03:52 That's not a class method in string; that's an instance method.
03:55 You send it to another string, you give it a second string, and it will create a new string for you since strings are immutable.
04:03 NSString is immutable.
04:04 It creates a new string that is the string you sent it to with the one you passed as an argument added on, right?
04:10 So there it's creating a new object for you, okay?
04:13 And a very interesting instance method that you can ask an object to do for you is mutable copy, okay?
04:22 So mutable copy makes a copy of an object but it's mutable.
04:25 So if you had an NSString and you send it mutable copy, you'll get back an NSMutableString.
04:29 Or if you have an NSArray and you send it a mutable copy, you'll get an NSMutableArray.
04:34 So that's another way that that happens that you're creating objects.
04:39 Of course, not all methods that return an object are creating an object like we saw in NSArray -- last object, and first object, and object date index.
04:47 Those aren't creating new objects; they're just giving you pointers to the objects that are in those array.
04:52 Okay? That should be completely obvious to you but just want to make it clear, you know, these are pointers to objects.
04:59 And you're allowed to have multiple pointers.
05:01 And this is normal pointers here being passed around.
05:06 Okay? So basically, unless a method has the word "copy" in it, then if it's returning to you an object that exists somewhere else, it's going to be returning a pointer to that object, okay, unless it has the word "copy" in it like "mutable copy" or "copy." And if the object that you're getting back doesn't exist somewhere, then it's going to make a new one for you.
05:27 All right.
05:28 That's it on creating objects.
05:30 Pretty straightforward there.
05:31 Okay. Nil, I already talked about this, that we can send messages through a pointer that is nil, i.e. that pointer does not point to anything.
05:39 And no code gets executed.
05:41 So if I do this init I equals obj method which returns an init, no code gets executed to execute method which returns an init; however, that message sending square bracket thing will return zero.
05:55 Okay? So that's important to know.
05:57 And zero is also what nil is.
05:59 So if you had a method that returned an object and you sent that message to nil, then you get back nil.
06:06 Okay? And we can use that, actually, to our advantage.
06:09 For example, in our thing we did on Monday, we did draw a random card, right?
06:15 Self.deck draw a random card.
06:17 And that returned nil if the deck was out of cards.
06:20 Okay? If the deck itself had been nil, that also would return nil.
06:24 So we can write one if that deals with the fact that we can't get another card, whether it's because the deck is empty or because there is no deck because the deck is nil.
06:32 Either way, the code's going to look exactly the same.
06:35 Okay? So you'll get used to that.
06:38 It's definitely different from other languages where you're protecting against sending messages to nil.
06:42 But you'll get used to it.
06:44 You do have to be careful.
06:45 If the return type of a message send is a struct because you don't get back a struct with all its members set to zero; you get back an undefined struct.
06:54 Okay? What's in there is undefined.
06:56 Okay? This struct is being returned to you on the stack.
06:59 You might get stack garbage, you might get zero.struct, you just don't know.
07:02 So you can't rely on it.
07:03 So here you should never rely on that in your code.
07:06 Okay? If you call a method, it returns a struct, you got to check to make sure you're not sending it to nil.
07:11 Okay? All right.
07:14 Dynamic binding.
07:15 So Objective-C handles the dispatching and calling of methods differently than languages that most of you are used to.
07:25 It does what's called "dynamic binding." Okay? And you'll see what dynamic binding is as we go through this slide.
07:32 But the important thing to understand about dynamic binding and about Objective-C is that there's a really, really important type in Objective-C called "ID," okay?
07:42 We call it "ID." We don't call it id by the way; ID we call it.
07:46 So here in that line of code I would say that's ID my object.
07:49 Okay? So I'm declaring a pointer, my object, which is a type ID.
07:54 So ID means pointer -- ID is a pointer, so we don't use ID star; ID is a pointer -- it means a pointer to an object where I don't know its class.
08:05 Okay? Of unknown type or unspecified type, okay?
08:08 So it's just a pointer to an object; I do not know anything about that object.
08:13 Really, all pointers in Objective-C are IDs in that the decision about what code to execute when you send a message to an object is not determined until runtime when you send that message.
08:26 Okay? When you send a message, it's essentially calling a function that's looking up the right code to execute for that particular class that you're pointing to at the time you send the message, okay?
08:37 That's called dynamic or late binding, okay?
08:41 And all message sends -- all of them in Objective-C -- are done this way, okay?
08:46 Now, what does this mean?
08:49 All right?
08:50 It means that -- well, is this safe, right?
08:54 Because you're worried, I'm sure, "What if I send a message to an object and it doesn't understand it?" Okay. Well, nothing stops you from doing that.
09:02 And not only that, if you do that, your program will crash.
09:05 Okay? It will raise an exception.
09:06 Unless you catch the exception, it will crash.
09:08 And so you're probably feeling like, "Wow.
09:11 These Objective-C programs must be crashing all the time because you accidentally send a message to an object; it doesn't understand that message." But actually, it doesn't happen.
09:19 Okay. Why doesn't that happen?
09:21 And there's really two reasons.
09:22 One is we use static typing a lot.
09:25 We don't use ID that much.
09:26 We use, like, NSString star.
09:29 Now, NSString star is exactly the same as using ID, except that the compiler, while it's compiling your code, knows that you at least intend that that pointer points to a string.
09:40 So if you tried to send a nonstring message to that pointer, it's going to complain.
09:44 It's going to, you know, give you warnings.
09:46 And so when you compile your Objective-C programs they should always have no warnings, and then you can be pretty sure that you're not going to have this problem where you send a message to an object at runtime and it doesn't understand it and it crashes.
09:57 Okay? So that's the number one way.
10:01 And the second way I'm going to talk about is that a lot of times we will check at runtime.
10:05 We'll look at that ID pointer, okay?
10:08 And we will check and see if it responds to something before we send it.
10:12 Okay? So you know about static typing, that's the NSString star S equals at sign X. This is really safe, really good, nothing bad's going to happen here because the compiler at compile time has a pretty good idea what you intend and it will warn you if not.
10:26 However, the compiler is not doing the binding between what codes executes at this time; it's just warning you.
10:34 It's syntactic sugar.
10:35 Okay? It's syntax that it can look at to warn you, but it's not actually enforcing anything here.
10:41 It's perfectly legal to say ID obj equals S, where S is the line before.
10:47 Okay? And that will not even generate a warning.
10:49 Because ID obj is a pointer to any kind of object; S is a pointer to any kind of object.
10:54 It's a pointer to a string, according to the previous line.
10:57 But since those are both pointers to objects, that's perfectly legal.
11:00 Compiler will not warn you.
11:01 This is a little bit of a dangerous line of code, right?
11:04 Because you just went from having S -- this nice variable that's typed and the compiler can warn you if you do the wrong thing -- to having an obj, which is this untyped pointer where you can send any message you want and the compiler's not going to warn you.
11:17 Okay? You can also do this NSArray star A equals obj.
11:21 Okay. Now you have NSArray variable that points to a string.
11:26 Now, that's extremely likely to cause a problem, okay?
11:29 This is also legal because NSArray star A is a pointer to an object; obj is a pointer to an object, so it allows this assignment.
11:38 Very dangerous.
11:39 Obviously wrong.
11:40 If these three lines of code are there, that's clearly wrong.
11:42 You would not want to have an NSArray pointing to an NSString.
11:45 Okay? So ID can be dangerous in this way.
11:49 And in fact, in the code that we've written we already did this kind of silently.
11:54 Remember that in playing cards match we put a line in there that said, "Playing card star other car equals other card's first object." Remember that?
12:02 Well, the method first object in an NSArray returns an ID.
12:06 If you go look it up in the documentation, look at its return type -- parenthesis ID.
12:12 Okay? So we just assigned a playing card to an ID.
12:15 So that object that came out of that array better be a playing card or we're going to crash at runtime.
12:20 And a little later in this lecture I'm going to show you how we can protect our code to make sure that we don't crash in this case.
12:27 Okay? Does everyone see why this is a little dangerous?
12:30 All right.
12:32 Questions about that?
12:35 Okay. And a reminder: Never use ID star.
12:37 ID star makes no sense because ID is a pointer.
12:39 So ID star would be a pointer to a pointer.
12:41 We don't do that in Objective-C, okay, especially a pointer to an ID [inaudible].
12:47 All right.
12:47 So to summarize all this I'm going to show you this example.
12:51 I've got two classes: I got a vehicle class, which has what method move -- you can move the vehicle around -- and I got a ship which is a vehicle, inherits from vehicle, and it's only got one method, shoot.
13:01 So this ship can shoot other ships.
13:02 And they can also move because they're vehicles.
13:05 Okay? So if I declare a local variable ship, ship S, which is a ship star, and I allocate init a ship, I can say "S shoot" or "S move" -- works fine, right?
13:16 Because ships implement shoot and they inherit move.
13:19 So everybody's totally happy here.
13:22 I can also do vehicle star V equals S. That's perfectly legal because V is a vehicle and S is a vehicle because it inherits its vehicle-ness from ship.
13:33 Okay. This is like deck equals playing card deck alloc init -- perfectly legal object to run in your programming, right?
13:39 Okay. But now let's try to say V shoot, okay?
13:43 Now, what's going to happen here?
13:45 All right.
13:46 At compile time you're going to get a warning because vehicles do not implement shoot; ships do but not vehicles.
13:53 So do you see why this is going to give you a warning?
13:56 Okay? What about at runtime?
13:58 This code will not crash because we know that V actually is a ship.
14:03 So this will work fine at runtime.
14:06 Okay? See that?
14:08 So this is where you get a warning at compile time; runs fine at runtime.
14:14 Okay? Now, what about this case where I declare an obj, okay, and it can be anything we want.
14:21 Okay? Alloc init it somehow and you say "obj shoot," okay?
14:26 No matter what obj is -- and I intentionally didn't tell you what obj is because it doesn't matter what obj is.
14:31 The compiler is not going to warn you here.
14:33 Anytime you send a message to obj, as long as that message exists somewhere, the compiler will not warn you.
14:39 Okay? At runtime, if obj is not a ship or some other object that responds to shoot, it will crash.
14:46 Question?
14:47 >> Is ID special in that way?
14:50 >> In what way?
14:51 >> Because it seems like it's a similar case where whatever you've assigned obj is a pointer to an object but it may or may not have this method.
15:06 >> Well, so the question is: Is ID special in that way?
15:07 You mean is ID special in that I can send it any message I want and the compiler won't warn me?
15:12 Yes. Because that's kind of the semantics of ID.
15:15 ID means a pointer to some object I don't know the class of.
15:18 So there's no way for the compiler to give you a warning.
15:20 So it just assumes "Okay, somebody responds to shoot.
15:23 So it might be this one, so I'm not going to warn you." So yeah, ID is special in that way, I guess.
15:28 That's why we don't want to use ID unadorned like this.
15:34 If I'd say obj some method name that doesn't exist, then it will warn me.
15:38 Okay? So if it can't find that method anywhere, no object that the compiler's ever heard of implements that method, then it will at least warn you.
15:46 Because then it's likely you had a syntax error.
15:48 You mistyped it.
15:49 Okay? And so the compiler is going to help you there.
15:51 So let's say I had an NSString star hello.
15:56 Okay? And I'm going to make it equal to at sign hello.
15:58 If I say hello shoot, the compiler's obviously going to warn me and say, "Strings don't respond to shoot." And at runtime this would crash because, of course, strings don't respond to shoot.
16:10 Okay, so this is all good.
16:11 This is the way we want things.
16:14 What if I did this, ship star hello ship equals cast -- okay, everyone knows about casting, right, all languages have casting pretty much; well, most languages that you know -- parenthesis ship star hello, okay?
16:29 This is perfectly legal.
16:30 And the compiler will not warn me, okay?
16:32 So I've now taken a string and put it in a ship star pointer.
16:37 And the compiler now thinks that that hello ship is a ship.
16:40 And so it's only going to complain if you do things to it that don't look like ship, even though we know we know that that is a string.
16:48 Okay. So casting can be super dangerous, just like in any language casting can be dangerous.
16:53 It can be dangerous here.
16:54 But we do do cast sometimes.
16:56 And the times we cast are the same kind of times we use ID, which is protected times.
17:01 I'm going talk about that protection on the next slide.
17:05 So if we then said hello ship shoot, okay, that would not generate a compiling error because hello ship is a ship star; however, it would crash at runtime because strings don't respond to shoot.
17:19 Everybody cool?
17:21 Yeah?
17:21 >> [Inaudible]
17:23 >> Okay, the typecasting really doesn't do anything; that is just tricking the compiler.
17:30 Okay? That's not even executing really any code per se.
17:33 It's when you send the shoot, it tries to dispatch that shoot to that variable, that hello ship variable.
17:39 The thing turns out to be a string, and it crashes right there.
17:42 You can also do this: ID hello shoot.
17:48 Okay? So hello is the NSString star, and I casted it to ID and sent it shoot.
17:53 And that will suppress all warnings as well because now I'm sending shoot to an ID.
17:58 And I just want to show you here that you can cast it right in line; you don't have to create another variable.
18:02 If you cast it right in line, you fake out the compiler.
18:06 Now, we don't want to be faking out the compiler.
18:07 Compiler is our friend.
18:08 It helps us find bugs, okay?
18:10 But this all can be done.
18:12 Okay? Mostly I put this up here to see the difference between the compiler catching something and it crashing at runtime, okay, and when it does which.
18:21 All right.
18:21 So when would we ever use this ridiculously dangerous thing of ID?
18:25 Well, someone asked earlier, "Can I have an NSArray that has different kinds of things in it -- some strings, some numbers, something else?" Absolutely you can.
18:33 And there's plenty of times when you absolutely want that, okay?
18:36 So it's great for that.
18:38 Now, other language like Java lets you actually tell the compiler that this array has strings in it so that the compiler, when you pull objects out, it knows what type they are and it can kind of help you out.
18:48 Objective-C doesn't have that.
18:50 So the compiler cannot help you with contents array.
18:52 Okay? So it's kind of your responsibility.
18:54 I'm going to show you how we deal with that.
18:56 The second one is -- remember the NBC talk?
18:58 I talked about all this blind structured communication, right, this blind communication.
19:03 Well, to have blind communication you got to have pointers to objects of types you don't know.
19:08 Okay? There's no way that the view can send the target action thing to the controller without knowing the class of the controller, unless the view can have some kind of pointer to a controller that it doesn't know the type of.
19:20 Okay? And that's big use of ID.
19:24 However, we need to protect ourselves, and there's two big ways that we protect ourselves against IDs.
19:30 One is introspection, which I'm going to talk about in the next few slides, which is we can ask an ID at runtime, "What class are you?" or "What methods do you respond to?" So that's a great way to protect ourselves.
19:41 And then another way is called "protocols." And protocols is a way using little angle brackets after an ID to say, "This is an ID, a pointer to some class I don't know what it is, but it responds to this set of methods that I'm going to define with this little angle bracket thing like UI scroll view delegate." And that's how we do the delegation and data source thing.
20:01 So we're not going to talk about protocols today because you don't quite need them.
20:04 We'll probably talk about them next week or the week after.
20:07 But that's another way we protect ourselves against ID by having like -- an ID with the angle brackets is kind of in between pure ID and static typing.
20:16 It's kind of in the middle, right?
20:17 Instead of static typing the type, we're just static typing the messages that the thing can respond to.
20:22 Okay? So it's kind of in the middle in terms of safety.
20:25 All right?
20:26 So let's talk about introspection, though.
20:29 There's a few introspection methods in NSObject.
20:33 I'm going to talk about three of them here.
20:35 Is kind of class, is member of class, and responds to selector.
20:39 So is kind of class and is member of class lets you ask an NSObject or anything that inherits from NSObject, "Are you of this kind of class?
20:47 Or is member of class means, "Are you actually this class?" Not this class or something that inherits from it, but actually this actual class.
20:55 And then response to selector says, "Does this object that this ID points to, does it respond to a certain method?" Okay? So the arguments unfortunately to these methods are really kind of wonky.
21:09 And just you're going to have to take my word for it on these ones because when I spit out the sentence in a second here that describes what the argument is, I'm going to use the word "class" four times and it's going to mean four different things.
21:21 Okay? So the argument is kind of class, you get by sending the class method class to the class, which will give you a capital C Class, which is the argument to the is kind of class method.
21:36 Okay? So there's this method class.
21:39 You see it there, NSString class.
21:41 It's a class method on NSString returns a capital C Class.
21:45 And that's the thing that's the argument is kind of class.
21:47 It's always of this form, obj is kind of class, open spare bracket, the class you want, class, close square bracket, closed square bracket.
21:54 Okay? So it always looks like this.
21:56 So just do it.
21:56 If you didn't understand my four-class sentence, just do it just like this, okay?
22:03 Once I see that an object kind of a class, then I might want to cast it.
22:07 You see here I'm casting obj to be an NSString star there because I know at that point it's an NSString star.
22:13 So it's okay to fool the compiler, or really I'm teaching the compiler a little bit more about what obj is by doing that.
22:19 Not really tricking it.
22:20 And it's perfectly safe to do that because I know that obj at runtime is that kind of class.
22:26 Okay? Questions about that?
22:28 Yeah?
22:28 >> [Inaudible]
22:29 >> Okay, the question is: What does the instance method class -- so I can say, you know, trying to think of an example where we use that, like deck.
22:42 I might say deck class, for example.
22:45 That returns essentially the same thing as here, and you probably could say is kind of class open square bracket instance [inaudible] class.
22:55 But your reader would pretty darn confused by that.
22:58 So there's an instance method and a class method; probably both return the same thing, capital C class, I believe.
23:04 But we would never do that here, so don't put an instance call there, just the class method you want.
23:10 Good question.
23:12 All right.
23:12 How about the selector one, the method one rather?
23:15 Okay. So methods, when we use them in this response to selector thing, we call them "selectors." A selector is really kind of an identifier for a method name because if you have the method shoot, it's the same selector no matter what class you're talking about implementing it in.
23:31 Even if they don't inherit from each other, they're completely unrelated.
23:34 You might have a gun class that says shoot and you might have a ship class that says shoot -- the selector shoot would be the same.
23:40 And we get that selector by saying at sign selector parenthesis, the name of the method, okay?
23:46 Shoot. And if the method has multiple arguments, we just put the colons in there.
23:50 So shoot at colon has one argument or add card colon at top colon.
23:56 We just say that, at sign selector, open parenthesis, add card colon, add top colon, close parenthesis.
24:02 Okay? And that gives us the selector, and we say responds to selector.
24:05 And that will tell us whether the object that we're sending responds to selector to responds to that method.
24:12 Okay? Now, these selectors, there's actually a type, kind of a type def in Objective-C for these selectors.
24:18 All caps SEL, kind of like all caps BOOL, right?
24:21 So this type def thing is added.
24:23 And you can declare variables that are of type SEL and store things in there.
24:29 And there are actually other methods besides respond to selector that take a selector.
24:34 For example, object has perform selector and perform selector with object, okay?
24:40 They will perform that method on another object.
24:45 Now, why would you ever want to do this?
24:46 Well, you might have some parameterized thing where you're going to do one of three different methods, depending on something the user chooses.
24:53 And you can say perform selector and then have three SEL variables, one for each method, and pass that as the argument you want to perform selected.
25:01 Perform selected with object, that method would have one argument.
25:05 So the selector name better be something colon because it's got one argument.
25:09 And the argument has to be an object.
25:11 So coordinate here would be some sort of object.
25:14 Okay? So just a little limitation.
25:16 It can only have no arguments or have one argument that's an object.
25:19 You can also do cool things like ask an array make all the objects in yourself perform this selector.
25:28 This is a very cool method.
25:29 And if you get used to using methods like this in Array, you'll find your code will shrink down really small because, you know, for ins and things like you have to really zoomed down to one-liners, make object perform selector, okay, or make object perform selector with object.
25:44 So that's an NSArray thing.
25:46 And of course, we do target action with selectors.
25:49 The method, if you wanted to set up target action, not doing control drag but actually setting up in code, is in UI control actually, which button inheritance from.
25:58 Add target colon, action colon.
26:01 There's some other arguments.
26:02 But you can see that add target takes an ID and then it takes an action colon, takes a selector.
26:07 So it says what message to send to what object -- what's the target, what's the action?
26:13 Everyone understand that?
26:16 Okay. So this selection stuff, pretty selector stuff is pretty powerful.
26:21 All right.
26:21 So let's take a look at how match -- the playing card match -- might be improved with introspection.
26:27 I'm going to go here back to Xcode.
26:31 And I'm just going to open back up Machismo where we left off here.
26:37 [ Pause ]
26:45 Okay. And then let's go down to playing card.
26:49 So here's playing card and here's match.
26:51 Okay. So you all remember match.
26:53 And here's the line of code that's a little bit of trouble.
26:56 Okay? Because this first object here, this returns an ID.
27:00 So what we could do here, for example, is we could say ID card equals this.
27:06 Okay? Just to be totally clear here.
27:11 So we got this card.
27:12 And then I can say if card is kind of class, playing card class, okay, then I'll do all this.
27:22 Okay? All right?
27:25 And I'm going to set the other card here to be playing card, star card.
27:32 So I'm going to cast it.
27:34 So now the compiler knows about this variable.
27:37 And from here on out, whenever I touch other card, it knows it's going to be a playing card.
27:41 And here I've checked at runtime to make sure that it's actually the playing card so that I'll never crash here.
27:47 Now, if you say match colon other cards and the other cards are like, some not playing cards, they're regular cards or they're strings or something, then that's okay.
27:57 This method's going to work fine because it's going to return zero, a score of zero, which is right because a playing card wouldn't match a string or any other kind of card.
28:04 Okay? Make sense?
28:06 See how we used introspection there?
28:09 So you will have to use introspection most likely in your solution to next week's homework -- not the one you're currently working on.
28:15 By the way, I should take time out to say I'd almost -- if I ever show you something in a lecture after I've assigned something to you, you almost never need it in that week's homework.
28:25 And I would tell you if that were the case.
28:27 Okay? You know what I'm saying?
28:29 So, like, you've got an assignment on Monday; I wouldn't be showing you things today that you needed for the assignment on Monday.
28:35 I've already shown you everything you need by the time you get [inaudible].
28:40 Okay? Question?
28:46 >> [Inaudible]
28:46 >> Okay. So the question is: Is introspection only used like this when you're pulling items out of Array?
28:50 And remember, I told you a couple slides ago there are two major times when we use introspection -- one is this.
28:55 Okay? Second one is all that MVC blind communication, right?
28:59 Target action, and delegation, and all that stuff.
29:03 Okay? So that's that.
29:06 Now let's move onto Foundation.
29:08 Okay? So we're going to talk about a Foundation framework here.
29:10 I'm going to really go fast through object, Array, dictionary, things like that because we've already seen a lot of Array.
29:16 I think you pretty much got a good feel for what it is.
29:18 So I don't want to waste the time talking about that.
29:20 We got a lot more new stuff to talk about.
29:22 But you know that NSObject is the base class for all objects.
29:25 It implements those introspection things.
29:28 It also implements this very important method called description.
29:31 Okay? So description, it just returns an NSString.
29:35 And it's supposed to return a string that describes this object.
29:39 Okay? When do we ever use this?
29:41 Two places.
29:42 One, NS log.
29:43 When we're debugging, we like to NS log percent at sign.
29:47 And when we do percent at sign, the matching objects get sent description, and that's what gets sent out.
29:53 Now, NSString implements a description by returning self.
29:59 Okay? NSObject implements description very badly.
30:02 It returns like the pointer, a string with the pointer in it or something.
30:07 Description becomes valuable when you implement it in your own classes.
30:10 So you could imagine implementing in playing card, or even in card you could implement description that would return self.contents.
30:18 Right? And then in the debugger there's a way -- in which you'll see this Friday's section -- there's a way to print an object in the debugger.
30:26 It will call description for you and return it.
30:28 So for card you'd see the contents.
30:30 So that's really cool.
30:31 And the string shows you the string.
30:32 Arrays and dictionaries implement description to print out the contents of the array.
30:37 So description's a really cool little function to know about in NSObject.
30:42 NSObject kind of implements this framework for copying, but it doesn't actually implement copy immutable copy.
30:49 If you look in NSObject, you'll see that these methods are implemented there or there's a protocol for them there.
30:55 Copy and mutable copy are -- the semantics of them vary from class to class.
31:01 So it's up the class to implement it, okay?
31:04 Don't be fooled by the fact that copy and mutable copy are in NSObject.
31:07 You can't just send copy to any object and it will copy it.
31:10 But NSArray, for example, NSDictionary, these things, they implement copy and mutable copy, and they do the right thing.
31:16 One thing to note about copy is if you send copy to a mutable object like a mutable array, you don't get a mutable array back, even though you just copied a mutable array.
31:26 You get an immutable array back, okay?
31:28 The semantics copy are, "Give me an immutable copy of this object back if possible." Okay? The semantics of mutable copy are, "Give me a mutable copy of this thing." No matter whether the receiver is mutable or immutable, mutable copy means give me a mutable copy; copy means give me an immutable copy.
31:48 Okay? Understand that?
31:51 And again, certain classes implement this; NSObject really does not.
31:56 You would have to implement it yourself if you wanted to have your objects be copyable, which is pretty rare by the way.
32:01 Really not generally doing that.
32:04 Okay. NSArray is an ordered collection of objects.
32:07 It's immutable.
32:08 When you create an NSArray, whatever objects are in it when you create it, those are the objects that will be in there for life.
32:13 You can't remove any, you can't add any.
32:15 All objects in an array are held onto strongly in the heap.
32:19 So as long as that array itself is in the heap, okay, as long as someone has a strong pointer to the array itself, all the objects that are in the array will stay in the heap as well because it has strong pointers to all of them.
32:31 Okay? You usually create an NSArray by sometimes calling a class method or even alloc init.
32:38 But usually most commonly we do that at sign square bracket thing, like how we created rank strings.
32:44 Remember rank strings in playing card, at sign, square bracket, and the elements?
32:51 That's usually how we create arrays.
32:53 Sometimes we'll create arrays by asking other arrays to add an object to themselves and give us a new array since they can't be mutated; they have to make a new one and give it back.
33:01 So that's another way.
33:02 And you know the basic, you know, get the count, object at index.
33:07 There's a lot of other really cool methods in an array.
33:09 You really should familiarize yourself with this class.
33:12 Okay. It's a lot of stuff.
33:14 We talked about make objects perform.
33:15 There's sorted array using selector.
33:18 So you give it a selector that takes another -- that basically gets sent to each object in the array and takes one of the other objects in the array as an argument.
33:26 So you got to make sure they have the right type of argument there.
33:29 And it will just use that to create a sorted version of the array and give you back a new array that's sorted.
33:34 Okay. So one line of code as long as you have a selector for a method that can compare two objects that are in an array, you can sort it.
33:41 Okay? So you really should know about all these kind of whacky things in NSArray.
33:46 Now, NSArray can't be modified.
33:49 Sometimes that's a limitation -- not as often as you might think.
33:54 But there's a mutable version of Array, of course, called NSMutableArray, which we've also used.
33:59 We usually create it using alloc init or sometimes we use Array with capacity, okay?
34:05 Array with capacity is -- that capacity argument is just performance hint.
34:10 Okay? It's not saying that the array starts out with that many items; it just means, "I think this array is going to have a hundred things in it." So creating an array with a hundred -- it's a performance hint only.
34:19 You know that NSMutableArray inherits everything from NSArray, of course, and then it adds add object, insert object data, move object at index.
34:28 And you know that you can use the square brackets notation, right, like self.cards open square bracket, index, closed square brackets to both put things into an array and get things out of an array.
34:39 Okay? And using that notation is really just calling object at subscripted index and set object at subscripted index.
34:47 Okay. It's just calling those methods; that's all it's doing.
34:50 But it looks really nice in your code to use those square brackets.
34:54 Okay? Enumeration, we saw how to do this for in business.
34:59 Don't forget that that control variable like NSString star string in my array -- you see the NSString star string -- that's essentially your casting, okay?
35:08 Your casting, whatever comes out of that array to be an NSString.
35:11 You're telling the compiler, "I know that what's in that array is strings." Now, if you don't know what's in there, you could say -- or if it's a mixed things -- you would say for ID obj in my array.
35:22 Then the iteration variable will be an obj and you'll likely want to use introspection to find out what the thing you got back is each time around the loop.
35:30 Make sense?
35:33 Okay? Next NSNumber.
35:35 All right.
35:36 NSNumber is a class that is used to wrap primitive types like integers, floats, doubles, Booles, things like that.
35:42 And why do you want to wrap them?
35:44 Usually because you want to put them in Array or a dictionary, okay?
35:47 So you can't put an int into an array; you need to have an NSNumber object.
35:51 You can create them with class methods like number with int -- that's a class number in a class method NSNumber -- or you can use at sign parenthesis.
36:02 Okay? So we already saw at sign square bracket for arrays, there's also at sign parenthesis, or even just at sign number if you want to create a number.
36:10 So you could say at sign three.
36:11 You could also say at sign 3.2, and that would create an NSNumber that would contain that primitive type.
36:16 If you put the parenthesis, then you could put things inside like calls to methods that return a primitive type, or e nums, or anything you want in there -- any expression that evaluates to a primitive time can be put inside of parenthesis.
36:29 You say at sign parenthesis and it will create an NSNumber with the result.
36:33 Okay? Everybody understand that syntax?
36:38 Okay. So other languages kind of have this autoboxing kind of stuff in there.
36:43 NSValue, I'm not going to talk too much about it.
36:47 It's essentially a way to encapsulate more complicated types than primitive types, so structs basically, C structs.
36:54 And NSValue knows how to wrap up a few different kinds of structs that are in iOS.
37:00 And you can go look at the documentations to see which ones.
37:03 One thing I'm going to give you a little tip right here, okay, sometimes a good way to wrap up a struct is to turn it into a string.
37:12 Then you can put it in the array as a string.
37:13 It's nice because you print it out in the debugger and you can see it really nicely.
37:16 And then there's ways to turn things from strings back into C structs.
37:21 So there are C functions in iOS that turn most of the structs in iOS into strings and then other C functions that turn the strings back into the structs.
37:29 So NSValue -- I think most of the time you can use strings.
37:34 It's probably more efficient to store something as an NSValue but, again, don't overoptimize.
37:38 Turning into a string is just as performant in the case you're using it.
37:43 It's nice because it's a string and it's easy to look at.
37:46 Okay? NSData is another Foundation class, just a bag of bits.
37:51 And we're going to be using NSDatas.
37:53 We'll talk about them more when we get to that.
37:54 But it's just basically a certain count of bytes, that's what NSData is.
37:59 NSDate is a date, right?
38:01 It has some internal representation.
38:03 It's probably the UNIX representation like the number of seconds since 1970 or whatever it is.
38:08 One thing to think about with NSDates, if you're going to put a date in your UI, you got to know what you're doing.
38:16 Okay? Why is that?
38:18 That's because dates vary dramatically all around the world.
38:21 And I'm not just talking about in French, you know, the month names are different, but you know, the order of whether the month comes first or the date comes first varies.
38:30 Some places on earth, some locales don't even use the same calendar as we use.
38:35 Okay? So there is an enormous amount of infrastructure in iOS for dealing with this.
38:40 Classes like NSCalendar, and date formatter, and things like that.
38:43 If you're going to put in your UI, familiarize yourself with all of that.
38:47 I don't have time to go over it all in lecture unfortunately.
38:50 But you just need to know that there's something you need to know.
38:53 You can't just say NSDate description and put it in the UI, okay?
38:58 Dates are a little bit complicated.
39:01 There's NSSet, which a set is an unword collection of objects, so the objects are unique.
39:06 Okay? So you put the same objects in there twice, it only goes in there once.
39:11 So sets are what you would think of in term of sets.
39:14 And there's actually an ordered set, which is like a cross between the set and an array.
39:18 And you can look those up.
39:19 You're not going to need those probably -- well, you might need set.
39:22 Set is nice because you can do things if you have -- set is very good at telling you whether something's in the set.
39:27 Whereas an array, if you had an array of a thousand things, the array might have to do some binary searching or -- well, I guess it can't even binary search because it doesn't know the order.
39:35 So it's got to look around in there.
39:37 It's hard for it to find things.
39:38 But a set is probably hashed and high efficiency.
39:42 It can tell you if you had a set of ten thousand objects and you ask it, "Is this object in there?" it could probably tell you really efficiently.
39:48 Okay? So there are some values sometimes sets versus Array.
39:52 Okay. Dictionary.
39:54 This is the second most important collection class behind Array probably.
39:59 It's an immutable collection of key value pairs.
40:03 It's like a hash table.
40:04 Okay? All the keys and values are held onto strongly, okay?
40:09 So if they're in there as a key or a value, then they're in the heap.
40:13 And they stay in there as long as the dictionary stays in the heap.
40:16 The keys and values, obviously, are both objects.
40:19 We'll talk about what the key has to do to be a key in a second here.
40:22 You usually create immutable NSDictionaries using another at sign syntax called "at sign curly brace." Okay. So it's at sign curly brace, key colon value, comma, key colon value, comma, key colon value, end curly brace.
40:37 Okay? So this is kind of like the at sign square brackets for arrays or the at sign parenthesis for NSNumbers.
40:42 This is NSDictionary's version of that.
40:46 You look up things inside a dictionary.
40:49 You can obviously do object for key.
40:51 That's a nice method for looking the value up by key.
40:54 But you can also use square brackets that looks kind of like looking up an array.
40:58 So if I had that colors dictionary that's showing right there and I had a string that was either green, or blue, or red, and I wanted to look it up, I can just say colors, open square bracket, the color string.
41:09 And it will look up that string.
41:10 It would return nil if there's no such key in there.
41:14 And it will return the value, the actual UI color.
41:17 So we're going to talk about UI colors in a couple slides.
41:20 Okay? So this is also really cool UI -- or syntax rather -- for accessing stuff.
41:28 These at sign square brackets, at sign curly brace, at sign parenthesis -- big improvement to Objective-C.
41:35 Of course, you can see how many objects in there.
41:38 You can do object for key to get it.
41:40 Key has to implement hash and is equal, right?
41:44 It's a hash table.
41:44 You have to be able to hash the key so we can have an efficient lookup.
41:48 But then two things might hash to the same thing, so you have to have is equal determine whether two objects that hash to the same thing are actually equal.
41:56 NSObject implements this very poorly, okay?
42:00 So you would never use a generic object or some subclass of object that you've created.
42:06 You would never use it as a key.
42:07 You're probably going to do pointer hashing.
42:10 So it would only do it if your objects are always unique.
42:13 In the heap there's never two objects that are the same that have different pointers.
42:17 Strings are excellent keys in NSDictionaries.
42:20 And so I would say strings are the key in a dictionary 90 percent of the time.
42:26 Okay? They're very good.
42:27 They hash really well.
42:28 They're very fast and do is equal, etc. Okay?
42:32 Of course, immutable, again, we'd like to sometimes add things to our dictionaries.
42:38 So we have a mutable version, NSMutable dictionary.
42:40 Usually create it with alloc init.
42:41 It has all the things of a dictionary, plus it has set object for key -- that adds a key value pair -- and you can remove objects, add entries from another dictionary, etc., etc. Looping through a dictionary looks like this.
42:54 You do for ID key in the dictionary.
42:57 So basically when you do for in on a dictionary, you're looping through the keys.
43:02 Okay? Now, of course, inside it's really easy.
43:04 You just say, "Value equals object for key," or even use the square brackets notation to get the value.
43:10 So you're kind of looping through the values, too, as long as your hashing is efficient, which it is if they're strings.
43:17 This is [inaudible].
43:17 It is possible to ask a dictionary, "Give me all your values as an array"?
43:23 And then you could for in through that array.
43:26 And whether that's more efficient than doing this probably depends on the size of your dictionary, etc., etc. Don't worry about it.
43:31 It's never going to be an issue in this class.
43:32 We're not going to have dictionaries of thousands of objects.
43:36 Okay? All right.
43:38 Next thing I'm going to talk about is not a class, or syntax, or whatever; it's a word, a phrase -- property list.
43:46 Okay? And I'm just going to define this term.
43:48 You need to know what this term means, property list.
43:50 A property list means a "collection of collections." Okay? What's a collection?
43:56 NSArray, dictionary, even string, NSData, NSNumber -- those are all simple collections if you want it think of them that way or they're the leaf nodes of collections.
44:05 So if you have any object graph that just has arrays and dictionaries, numbers, strings, dates, and datas, then it's called a "property list." So just for an example, if you had an array of strings, that's a property list; an array of arrays, and those array contain property lists, it's the property list.
44:23 Okay? So any arbitrary graph.
44:24 But as soon as you have any object in there that's not one of these things or they're mutable versions -- that's allowed, too; so you can have NSMutableStrings or NSMutableArrays in there -- then it's a property list.
44:37 Okay? A dictionary is only a property list if all of its keys and all of its values are property lists.
44:43 Okay? So a dictionary that keys are strings, and values are arrays, or other dictionaries of property lists, that would be a property list.
44:52 Why do we define this term?
44:54 Because there's a bunch of API throughout iOS that you're going to see that takes a property list as the argument.
45:01 But property list is only a phrase we define, so it's probably going to take an ID.
45:06 Okay? It's going to take an ID.
45:07 It might take an NSArray or an NSDictionary, depending on the API.
45:11 But it's basically saying in its documentation, "The argument to this is a property list." So even if it's an array, it's got to be an array of property lists.
45:20 If it's a dictionary, it's got to be a dictionary that has only property lists with keys and values.
45:23 If it's an ID, it's got to be an array, or a dictionary, or a string, or number.
45:27 You know what I mean?
45:28 It's got to be a property list.
45:29 Okay? Make sense?
45:30 And in fact, I'm going to show you one class that only operates on property lists, which is NSUserDefaults.
45:37 So NSUserDefaults is this one shared dictionary essentially that persists, even across application launching.
45:46 Okay? Exiting and launching.
45:48 So it's like a permanent NSDictionary kind of.
45:52 Everything that's stored in an NSUserDefault database has to be a property list.
45:57 Okay? So it's not a full-on database, though.
46:01 All right?
46:01 It's pretty small.
46:02 It's not really high performance.
46:04 So you only want to store small things in there.
46:07 Okay. You don't want to be storing huge images or anything like that, you know, turning them into NSDatas or something and storing them.
46:13 You really don't want to do that.
46:14 Small strings, and arrays of strings, and NSNumbers, dates maybe -- those kind of things is okay.
46:24 Its API. To access it, you call this class method on NSUserDefaults called "standard user defaults." And that will give you an instance that is shared across your entire application.
46:34 It's like a global.
46:35 Okay? There's only one of these things.
46:38 And you send messages to it like this set array for key.
46:42 There's also set double for key, set object for key.
46:47 That object would have to be a property list.
46:49 So it's kind of like a dictionary but it has these extra method like set double for key so that you can store primitive types in there without having to turn them into NSNumbers first.
46:59 You know, it kind of gets the type checking of versus just set object for key where it doesn't know whether that's a double or not, etc. And some of this -- because now have the autoboxing, you know, the at sign parenthesis business -- some of this API we don't really need that much anymore.
47:14 But it's all still in there.
47:16 Yeah?
47:17 >> [Inaudible] So in this property list idea, does that have to cascade down through all of its sub?
47:25 >> Yeah. So the question is: Does the property list idea have to cascade down through all of the sub things?
47:28 And the answer is yes.
47:30 A property list, for it to be a property list, everything in the entire object graph has to be a property list.
47:36 All the way down.
47:37 Okay? No exceptions.
47:39 And if you were to, for example, call set object for key and you passed it something that somewhere down a leaf node was a card, right, or some nonproperty list thing, this method would raise an exception and say, "That's not a property list," okay, at runtime.
47:53 So it would crash your program.
47:55 The other thing to remember, though, is once you've gotten this standard user default instance and you've stored what you want, you have to call this method synchronize on the instance, okay?
48:06 So NSUserDefault, standard user default, synchronize.
48:09 That's what makes it permanent.
48:11 So you write a few things, a little batch, and then synchronize.
48:15 Okay? Don't forget to synchronize.
48:18 If you were to set some things in there and your app crashed before you did the synchronize, it would not get synced.
48:25 Okay? When your app launched again it would be gone, the stuff you put in there.
48:30 Okay? The last thing really I'm going to talk about that's kind of in the core part of Foundation is NSRange, which is just a C struct.
48:40 It's exactly what you think: It describes a range.
48:42 This might be a range in a string or it could be a range in an array.
48:45 It's basically a starting location, that's the NSUInteger location and a length -- how many characters or how many items in the array?
48:53 There's an important constant called NSNotFound.
48:58 All right?
48:59 NSNotFound is the value of location in a range that was not found or that is otherwise invalid.
49:06 Okay. So it's, like, search for a substring in a string and it couldn't find it, you're going to get a range back that the location is going to be NSNotFound.
49:17 Everyone understand that?
49:19 There's also this thing, NSRangePointer.
49:22 That's basically just an NSRange star.
49:25 Okay. Now I told you in iOS we don't really put structs in the heap and we don't.
49:31 This NSRangePointer is for call by reference ranges.
49:35 Okay? So some methods will take an NSRangePointer as an argument -- one of its arguments -- and what it's saying there is, "If you pass me a pointer to a range, I'll fill it in with some information." Almost always you can pass null there and it won't fill the information in because you won't be pointing to a range.
49:50 But it's for reference.
49:51 Everyone know what it means to call by reference?
49:55 Question?
49:56 >> Just out of curiosity, why are you using unsigned or why did Apple choose to use unsigned on its range.
50:05 It seems like you can't represent a range over negative numbers.
50:10 >> Yeah. So the question is: Why did Apple choose to make location be an unsigned integer?
50:15 In other words, why can the range only be a positive range?
50:18 And I think the main reason they did that is, you know, they designed NSRange for their own purposes, like ranges in arrays, ranges in strings.
50:27 They never want to represent that.
50:28 And I will bet you dollars to doughnuts NSNotFound is either the maximum integer or it's minus, you know, whatever, negative, which sometimes are the same thing, right?
50:38 If you know how computer science works, a lot of times it's all the bits inverted, that's minus one that also would be at the end of the range.
50:44 So I think it's just because they didn't need it for anything else and they wanted to make their API clearer possibly.
50:51 I don't know.
50:52 I don't work at Apple -- never did -- so I don't really know why they did that.
50:58 Okay. So that's really kind of it for the Foundational stuff.
51:01 I am going to talk about some more classes in Foundation.
51:03 But first we're going to take a little detour and talk about a couple classes in UIkit.
51:07 Okay? And those are colors and fonts.
51:10 All right.
51:11 So UIColor, super simple class, represents a color.
51:15 The color can be represented in so many different ways, RGB -- red, green, blue, right?
51:21 HSB, that's hue, saturation, and brightness.
51:23 It could even be a pattern.
51:24 Okay. So you can have a color that is a UI image pattern in there.
51:28 And when you draw with that color, it will draw with the pattern.
51:31 So color, super powerful but nice and simple API.
51:35 Colors can also have alpha.
51:38 Okay. How many people in here do not know what alpha is?
51:41 Never heard the phrase "alpha"?
51:42 So everybody knows what alpha is.
51:44 Okay. So that's a first.
51:45 So alpha, which in computer graphics is how transparent it is -- one being fully opaque and zero being fully transparent.
51:53 You can create colors that are partially transparent.
51:56 And then if you draw with them, you'll be able to see behind where you filled in.
52:00 So colors are really cool.
52:02 There's a handful of kind of standard colors -- the green color, red color, purple color, whatever.
52:09 You can look in its documentation to find those.
52:12 They're just class method.
52:13 There's also a few methods in there like the light text color, which is the shade of gray for light text, disabled text, or whatever.
52:19 So you can look at all that.
52:21 Okay? So colors are simple.
52:22 Fonts, not to simple.
52:25 Okay? Now, fonts in iOS 7 are incredibly important to get right.
52:32 Okay? A huge percentage of good iOS 7 UI design is picking the right fronts, and using fonts in the right way, arranging fonts on screen in a nice way.
52:44 Super important.
52:45 So there's a lot of support in iOS 7 that's new that is basically about making it easy to do the right thing with fonts.
52:52 So I put up some examples of some iOS 7 apps here.
52:55 And you can see how front and center fonts are on all these things.
52:59 Okay? If you had ugly fonts here or you didn't have bold, or you had, you know, fronts that were too smashed together or hard to read or the wrong color, these UIs would be, you know, impossible to decipher or very difficult to decipher here.
53:16 So color, and background colors, and, you know, the size of fonts, and all these things are all critically important in all of these applications.
53:26 Okay? So we're going to talk a little bit about how to deal with this and what's in there for iOS 7 to make this happen.
53:34 Unfortunately, I don't have enough time in lecture in general to go through all of this.
53:39 I'll kind of distribute little bits of wisdom about it as we go through various UIs in lecture, and demos, and things like that.
53:49 What I'm going to try and give you today is just the basis for how we present text on screen, okay?
53:55 What the primitives are for that and how we do it in the right way so that we get consistency.
53:59 See, the one thing about all these apps -- do you see how the bold font, and the fonts you can click on, and the kind of little subheading fonts, they're all related fonts, same family -- maybe, maybe not.
54:13 But they're related.
54:14 They're the same sizes.
54:16 They look the same.
54:17 So all the apps kind of have a similar look, okay?
54:19 That's because they're all using fonts properly.
54:21 Okay? So let's talk about fonts.
54:24 The most important thing to understand about fonts is that if you're displaying user content -- okay, that the user's information.
54:31 So in the calendar that's the appointments, and the days of the week, and the month, and all those things.
54:37 In the weather it's the temperature, and the name of the city, and things like that.
54:41 In the timer app it's the city that the clock is in.
54:46 So if it's user content -- in other words, it's not the text on a button, okay?
54:51 It's not a text on a button that user's clicking like edit or something like that.
54:55 Then you want to use a preferred font, what's called a "preferred font." And so you want this incredibly important method.
55:01 If you only learn one method in all of UI font, it's this iOS 7 method called "preferred font for text style." Okay? The text style argument is a string.
55:10 You use a constant that you're going to look up in UI font descriptor, actually.
55:14 If you go through UI font, you can link click through and find it.
55:18 And so there's the body style.
55:20 So that's text that's in the body, the main part of what's being displayed.
55:24 So like, in an appointment that would be -- like in a calendar item that would be the actual information about what's going to happen at that appointment.
55:32 And then there's a headline style.
55:34 So that would be, obviously, a header.
55:36 There's footnotes, captions, like a caption on an image, things like that.
55:40 There's about, I think, eight or so of these.
55:43 And you should familiarize yourself with what circumstances semantically those things should be used in.
55:49 And then when you want a font in your app, you should be using one of these.
55:53 Okay? For user content.
55:55 There's also system fonts.
55:57 These are what goes on buttons.
55:58 Okay? Don't use the system fonts for user content.
56:02 Okay? Sometimes it's okay to use a preferred font on a button.
56:06 It depends on whether the title of the button might change, depending on user's, you know, content.
56:11 Basically it's the user's content on a button.
56:13 That would be okay.
56:15 But you generally wouldn't want to use system fonts for user's content.
56:18 Okay? So this is what's on a button, what's -- you know, that kind of thing.
56:26 All right.
56:26 UI font descriptor.
56:28 I put some extra slides in what I posted that talks more about UI font descriptor.
56:34 I'm not going to go through them here.
56:35 You can look through them, just kind of get a little bit of a hint for UI font descriptor.
56:40 But the bottom line is: Fonts are designed not by computer programmers but by artists.
56:46 Okay? Artists design fonts, and they've been designing them for hundreds of years.
56:50 Yeah, probably couple hundred years since the ledgers, since presses were made.
56:56 I don't know when Gutenberg was exactly.
56:58 Testing my history here.
57:00 But those were designed.
57:02 You know, back then you actually etched on pieces of lead or whatever.
57:06 Now they're designed in, you know, PhotoShop or Illustrator probably type, you know, vector graphics designing tools.
57:14 And the problem with that is that they don't fit what we computer scientists want, which is we want the bold version of this font, we want the italic version, we want the narrow version.
57:26 Okay. Unless the font designer actually designs a bold font or an italic font [inaudible], we don't get it.
57:32 Okay? We don't get one of those.
57:34 We could try and somehow scrunch it up to look more bold, but that usually looks, like, bad.
57:40 Okay? That does not look good.
57:42 So UI font descriptor's new in iOS 7.
57:44 It attempts to put categories on fonts that defy categorization.
57:52 Okay. So the UI font descriptor has a lot of knowledge in it about faces and is there a bold version of this, is there a condensed version, is there an italic version?
58:03 And so it maps that into something we, as computer scientists, want to do because we want to put something in bold on the screen.
58:10 Okay? So that's what UI font descriptor is all about.
58:13 Even size, by the way, is designed into a font often, okay?
58:17 A designer of a font will design a larger S with a little more curve here and there than a smaller S. Okay?
58:26 Size is not just a matter of vector graphic zooming in and out -- sometimes, it depends on the font.
58:31 So anyway, look at that, at slides that are in there to try and figure that out.
58:35 There's nothing you will have to do in your homeworks that is font descriptor.
58:39 You might have to do fonts but not font descriptors, I don't think.
58:43 Okay? You might want to if you want to do some advanced stuff.
58:48 So understand, though, that, yeah, when you do a font descriptor and you ask it for a bold version of a font, you might not get a bold version.
58:56 You'll get the best thing it can come up with, but it might not actually look bold, depending on what font it is and whether it has a bold, etc. Okay.
59:04 So now let's talk about how text looks on screen.
59:07 Well, the font is a big part of how text looks on screen.
59:10 Depending on which font you pick, that's going to determine a lot of what it looks like.
59:13 But there's a lot of other things that determine what a font looks like on screen.
59:17 For example, is the thing underlined?
59:20 Is it outlined?
59:21 Okay? How strongly stroked is the outer edge of the font?
59:27 Okay? Those things are all kind of independent of the font.
59:29 You can apply these things to any font.
59:32 So there's a new class that you're going to learn that's in Foundation called NSAttributedString.
59:37 And an NSAttributedString, very, very simple.
59:40 It's like -- it is not an NSString -- but it's like an NSString where every character has a dictionary of attributes.
59:47 And those attributes are like underlined, or stroke width, font, etc. Okay?
59:52 Now, the reason I say it's like NSString -- it's not a subclass of NSString.
59:57 You cannot send it string messages, okay?
59:59 So that seems like a significant restriction.
01:00:01 And it is, and we'll talk about how we're going to deal with that in a second.
01:00:07 You set the attributes simply by calling -- sorry, this is NSAttributedString.
01:00:13 It's immutable -- immutable -- not modifiable.
01:00:16 So you cannot set the attributes of an NSAttributedString.
01:00:19 There is a mutable attributed string; we'll talk about that in a second.
01:00:22 So you get the attributes by calling attributes at index.
01:00:26 And it will return you a dictionary with all the attributes for the character at that index.
01:00:30 And that NSRangePointer, if you pass it a pointer to a range struct, it will fill it in with "How many characters have the exact same attributes?" Okay? So it's basically you specify the location that you want the attributes and if a whole bunch of characters have those exact same attributes, it will return that range if you ask it.
01:00:48 Does that make sense, what that range is?
01:00:52 It's basically just telling you how many characters have the attributes you asked for at that character.
01:00:57 You can pass null if you don't care and just want to know the attributes of that character.
01:01:03 So NSAttributedString is not a string.
01:01:06 But we want to do string-like things.
01:01:08 We want to search for other substrings and things like that, that we do on a string.
01:01:13 So there's a method in NSAttributedString -- really important one -- called "string." Okay? And this will return an NSString that you can then search in or do all the string things you want.
01:01:24 For example, if we wanted to search, there's a method in NSString called "range of string," which returns an NSRange that tells you where a substring is in a string.
01:01:35 And so we can just say we have an attributed string lying around and we're looking for some substring; we just say attributed string string, range of string string, and we'll get the range back.
01:01:44 Okay? Now, that string method is guaranteed to be very high performance because you're doing this all the time.
01:01:52 You want to look at the NSAttributedString like a string.
01:01:55 So it's high performance.
01:01:56 However, it's also volatile.
01:01:58 The bottom line is this thing is probably returning you a pointer to that NSAttributedStrings' internal data structure, or some parts of it, or something.
01:02:06 You don't really know what it is.
01:02:08 You know whatever it returns is an NSString.
01:02:11 But so if you want to keep that thing around for more than just right there where you call it, make a copy of it.
01:02:17 Okay? Then you have a copy of the NSString.
01:02:19 You can hold onto it.
01:02:20 You almost never need to do that because you're almost always operating on the string right there in place like this -- a range of string.
01:02:26 You're just trying to get it.
01:02:27 Okay? Okay.
01:02:29 So that's string.
01:02:30 Very important property in NSString.
01:02:31 So there is a mutable one.
01:02:33 Okay? And mutable one, it does inherit from the nonmutable attributed string.
01:02:41 But it's not an NSString or an NSMutableString.
01:02:43 It's an NSAttributedString.
01:02:46 And it adds these methods to add attributes and set attributes at various ranges inside the attributed string.
01:02:54 Okay? Exactly what you would think.
01:02:55 And we're going to talk about what's in these dictionaries in a couple slides.
01:02:59 Now, what if you want to modify the characters in a mutable attributed string?
01:03:05 Okay? Exact same thing as the attributed string.
01:03:08 When you want to look at the characters, you call this method mutable string.
01:03:12 And it will return an NSMutableString.
01:03:14 And believe it or not, if you modify that mutable string that you get back, the mutable attributed string, its attributes will track your changes.
01:03:24 So like, if you insert some text, the new text will get the attributes of the character right where you inserted it.
01:03:30 Okay? If you delete characters out of that mutable string, then the mutable attributed string, those character attributes will just go away.
01:03:38 Make sense?
01:03:39 So these classes -- NSMutableString and NSMutableAttributedString -- are in bed with each other, just like NSAttributedString and NSString are in bed with each other.
01:03:48 Okay? I don't know how they did it at Apple, but it's really nice because it makes it really easy to manipulate both the characters and the attributes in an attributed string.
01:03:59 Okay? Okay.
01:04:00 So what kind of attributes are in those attributes dictionaries?
01:04:03 One of the big ones is the font.
01:04:06 Okay? So this is a dictionary.
01:04:08 The key for the font is NSFontAttributeName.
01:04:11 Okay? And you can look up these keys by going and looking -- if you look up NSAttributedString in the documentation, there's a link there, which is UIkit additions to NSAttributedString, and all the keys that I'm going to talk about are there.
01:04:25 And one of the keys is NSFontAttributeName.
01:04:28 And the value of that is a UIFont.
01:04:32 So this is where you would get a preferred font of a certain style, like a headline, let's say, in this case.
01:04:38 Okay? So if I had a dictionary that just had this in there -- nothing else -- the default text color is black.
01:04:45 Probably my letter A would like look that.
01:04:49 Okay? What if I added this key value pair to my dictionary?
01:04:53 NS Foreground Color Attribute Name, UIColor, blue color.
01:04:56 So here the key is this foreground color attribute name; the value is a UIColor.
01:05:01 So that changed it to blue.
01:05:03 Okay. And I could change it to green if I wanted to.
01:05:06 Be a little bit careful when you create an attributed string that has colored text because in iOS 7 the color of text sometimes is an indicator to the end user what they can touch.
01:05:18 Okay? And so if -- turns out apps in iOS kind of have a color theme.
01:05:25 The default is blue.
01:05:26 That's why on Machismo buttons that we make will be blue.
01:05:31 But they can be different colors like orange.
01:05:34 It depends on what tint you want your thing to be.
01:05:36 But whatever your color is of your app, that color you can usually tap on.
01:05:41 Okay. That's the color of text on buttons, text at the top of the screen to navigate places.
01:05:47 So be careful not to set anything else to be that color unless you can tap on it.
01:05:52 Okay? Be real careful with color.
01:05:54 There's also stroke with attribute and stroke color.
01:05:58 The with attribute -- and pay attention to this because you'll need this probably for your homework -- it's an NSNumber.
01:06:06 If it's a negative NSNumber, then that means fill glyph, you know, the A fill it, and stroke around the edge.
01:06:16 If it's a positive number, it means just do the stroke around the edge and the middle is transparent.
01:06:22 Okay? What else can we have?
01:06:25 Underline style attribute name.
01:06:27 So that's an NSNumber that has an e num, one of NS style underline style single or double.
01:06:32 Or there's also NS underline style none.
01:06:35 That would be no underlining.
01:06:36 There's also background color.
01:06:38 So here just to show you this is possible, I set the background of this glyph to be a transparent yellow.
01:06:46 Okay? It's thirty percent visible, thirty percent towards opaque yellow.
01:06:51 So you see how you can see the chalkboard shown through there?
01:06:55 I don't know if that will show [inaudible].
01:06:57 But here hopefully you can see -- I can see through that yellow background.
01:07:02 Okay? In your homework, you might want to think about using transparent colors somewhere else.
01:07:07 Okay. Not the background of a character or maybe the fill color or something.
01:07:11 Anyway, okay.
01:07:12 So transparent colors good.
01:07:14 Okay. So hopefully you're all getting a feel, then, for how we build this dictionary.
01:07:17 Okay. All we need to do is set the attributes of the characters that we want to have this particular set of attributes.
01:07:25 Okay? So where do we use attributed strings?
01:07:27 So I can create an attributed string.
01:07:29 It's got all these attributes.
01:07:31 Okay. Where do I use it?
01:07:32 Well, I can use it in a button.
01:07:34 Okay. I can set the title of a button to be an attributed string.
01:07:37 That might be useful for your homework.
01:07:40 We can create a UI label that has an attributed string.
01:07:44 And a very important class, which I'm probably going to talk about next time, which is UITextView.
01:07:50 UITextView is like a UILabel, but it's editable, selectable, scrollable, etc. Okay?
01:07:57 So let's talk about button.
01:07:59 Actually, I'm not going to talk about button, except for to say it's important for your homework.
01:08:06 It just has a method -- set attributed title -- just like it has set title for a state, it has set attributed title for state.
01:08:14 And you're going to want to use that.
01:08:16 It's also possible to draw strings directly on screen.
01:08:20 But we haven't talked about drawing on screen directly yet.
01:08:23 So we'll postpone until we talk about that next week.
01:08:26 But we will be able to draw attributed strings on screens directly, just like we can draw lines and things like that directly on screen.
01:08:35 UILabel has a property, it's an NSAttributedString called "attributed text." It's just like the text label, which is an NSString, which we've already used in this class, we like the score label and the flips label.
01:08:48 We set the text property.
01:08:49 So there's an attributed text property.
01:08:51 And you just set the property via an NSAttributedString instead of an NSString.
01:08:55 And that's it.
01:08:55 Unfortunately, it's read-only.
01:08:58 Okay. It's immutable.
01:08:59 That property you see is not an NS Immutable Attributed String; it's an NSAttributedString.
01:09:04 So if you want to change the attributed text that's on a UILabel, you have to get the label, make a mutable copy of it, modify it however you want, and put it back.
01:09:14 Okay. That's if you have an existing label and you want to make it be blue instead of green or something like that.
01:09:19 You have to get it, create a mutable copy, modify the attributes, put it back.
01:09:27 Okay? You don't need to do this very often on labels.
01:09:29 Labels don't really have attributed text on them that much.
01:09:33 Maybe to set the color.
01:09:35 Possibly if they're specialty labels that are kind of specifying something that's not just normal text.
01:09:41 So it's not that common to do UILabel.
01:09:45 So that's all I'm going to cover for today, I think.
01:09:52 We do have a Friday section.
01:09:53 The time is being confirmed to me probably as I speak right now.
01:09:58 I will post that for you on Piazza.
01:10:01 It's on Friday.
01:10:02 I believe it's going to be at 1:00 o'clock on Friday in 102.
01:10:06 Okay, unit 102.
01:10:07 But don't hold me to that yet.
01:10:09 Look at Piazza.
01:10:10 We're going to be talking about debugging.
01:10:13 There are some new debugging things for iOS 7 that are pretty cool.
01:10:16 We'll get to a couple of them.
01:10:17 And we're also going to talk about Xcode tips and tricks.
01:10:20 So command key combinations that are really valuable to have, how to set some preferences up to make your experience a little nicer.
01:10:27 So it's totally optional.
01:10:28 You don't need to go there.
01:10:29 A lot of you know Xcode.
01:10:30 You're probably used to debugging, at least in other languages.
01:10:34 So, you know, if you miss it, it's not going to be the end the world.
01:10:37 But it might be valuable.
01:10:39 Next Monday I'm going to talk about UITextView since it's the most important user of NS Mutable Attributed String.
01:10:47 Okay? And then I'm also going to talk about the radio station from MVC.
01:10:52 Remember that MVC model?
01:10:53 I told you that sometimes communication happens by radio station, where you broadcast and some other objects tune in.
01:10:59 We're going to talk about doing that.
01:11:01 And then I have a big demo that does attributed strings, and text views, and all that stuff.
01:11:07 And then we're going to go start talking about the view controller lifecycle, okay, which is your view controller.
01:11:12 It comes into existence.
01:11:14 Things happen to it.
01:11:15 It appears on screen and goes off screen, changes size, things like that.
01:11:19 And then it goes away.
01:11:20 Okay. It goes off screen and maybe even disappears.
01:11:22 And as all that happens, you get notified by the system.
01:11:26 Okay? And it's important to know when you're going to get notified and what to do where in terms of that notification.
01:11:30 So we'll be talking about that on Monday, view controller lifecycle.
01:11:33 Super important one for your next homework.
01:11:36 You next homework might go out on Monday; might go out on next Wednesday.
01:11:38 I'm not quite sure yet.
01:11:40 But in case, it will be due a week later.
01:11:43 So that's it.
01:11:44 And if you have any questions, I'll be here.
01:11:47 And I'll see you next time.
01:11:50 >> For more, please visit us at Stanford.edu.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment