[ Silence ] ^M00:00:06 >> Welcome back. First thing first, we have a new team member, Chris Gerber [assumed spelling]. So, some of you probably already heard from him as he being your point person, but he's here to help. Second, don't forget that your project is due next Wednesday. So we are diving into iOS/Objective-C today. But you still need to keep up with your project that still has to do with the JavaScript and HTML. OK. So, first we're going to recommend some books. David always recommends this one. You're going to want to make sure that your book is up to date with all the new iOS versions. So iOS 7, it was a very recent development. We are only going to be be dealing with iOS 6, plus I think iOS 7 isn't like officially available for couple of months. So, iOS 6 is what you're going to want to be using. When you start going back versions of iOS, things start changing pretty significantly. You don't want to go back to like iOS 4 before because things are going to be substantially different. So, look for iOS 6 things. Another book that I've never looked at but is supposedly also pretty good is this one. And I added this slide just before because this is one the actually use just to catch myself up with everything. It's a pre-preview of a book and I found it to be pretty good. I feel obligated to say like he does at the top of the page like if you find it useful you might want to consider actually buying the book. But that pretty much everything is in here. OK. So before we get into Objective-C, you first need to touch on C. So, it's important to remember that Objective-C is a proper super set of regular C. So like any Objective-C program that you write, you could write valid C all throughout the Objective-C program. We're not literally everywhere. But everything you know from C is still applicable in Objective-C. So, first, show of hands, who know C or any C? All right, that's better than I was anticipating. And another show of hands, who has any experience with any object-oriented language? All right. Cool. So, we'll do a really quick intro to C just to refresh you on everything. You'll probably recognize that a lot of it is pretty similar to JavaScript, so probably still pretty fresh. So, your very standard "Hello World" program. What does hash includes, standard IO.H2. What is standard IO.H? ^M00:02:51 [ Pause ] ^M00:02:53 I Think I might have heard someone say. But it's a header file. It literally just contains like--we'll see like the declarations of the functions. So we'll see more examples of those later. Those are still going to be pretty important in Objective-C. Here we see, we are declaring a main function. So just like in C we declare a main function, in Objective-C you are also going to have a name function. And what are these guys, int argc and con char star argv? What are those? Command line arguments. So int argc is how many arguments were passed at the command line and con char star argv are--what those arguments were. And then we just printf, will be--we'll see that once we got to Objective-C. We're not going to be really using printf anymore, but pretty standard program. So statements--that is a statement. Variables, you just declare them int n or say int n equal 0. That's going to be the same when we get to Objective-C. We have all of our regular primitive date types, char, double float, int long, and then the modifiers like unsigned int and unsigned double, and printf. So, if we--let's go into--We'll have a whole bunch of example programs up. And we have a whole bunch in C and Objective-C. We're not going to go through all of the C ones because a lot of them will just be tedious. But if you feel you need a refresher, you can just go back and look at all these. So, we'll look first C one, hello C. ^M00:04:35 [ Pause ] ^M00:04:38 OK. So, this is what we just saw before up there. And printf, remember, takes these modifiers such as percent S. ^M00:04:49 [ Pause ] ^M00:04:52 That are going to then be a comma separated list of things at the end of the printf call that you're going to fill in. So like percent S, it's expecting a string to fill in that percent S. And if instead we did int n equals 50, then we could do percent D and pass in the variable N. So that's how we're going to use printf with--that's how we print variables. And you'll see that these format specifiers just percent S and S percent D for integer. Those are going to carry over into some Objective-C areas. ^M00:05:29 [ Pause ] ^M00:05:34 Plus, all of these primitive data types, remember, that Objective-C is a super set of C, these still exist. ^M00:05:42 [ Inaudible Remark ] ^M00:05:43 Yeah? >> Do we still we have link to the book, the increment book? ^M00:05:47 [ Inaudible Remark ] ^M00:05:48 >> The slide will be online later. But if you want to look it up now-- >> Thank you. >> Yeah. And feel free to stop me at any point with questions. ^M00:05:57 [ Pause ] ^M00:06:14 It's good. Oh, yeah. OK. So the Boolean expressions, the very simple ones that you should--all be used to at this point. Conditions, we have a regular if-elses. Loops, we have for loops. So in JavaScript, you also have the, like, for in. You'll also see that in Objective-C. Regular C doesn't' have that. So we have a regular for loop, regular while loop, regular do-while. And all of those will still be usable in Objective-C. So, casting is an interesting case where it's exactly the same between C and Objective-C. You're going to see, you might be needing it a lot more once you get to Objective-C. So, in C, there are only so many cases I can possibly think of where it wants a cast. Like one example is if I want to do like 3 divided by 5. You know, how like if we just do the integers then 3 divided by 5 is going to be 0. So I might want to cast 3 to a float so that it actually does like floating point division. So that's one scenario I can think of where I want to cast. Once we get to Objective-C and we start dealing with classes and things, then we're going to want to cast like we'll see more of this but like supertypes to subtypes and subtypes to supertypes. So casting, you'll want to be comfortable with it. And then Pointers, they won't be as important in Objective-C but you're still going to have to deal with them. So, we have just the type of a pointer--let's actually look just an example. ^M00:07:51 [ Pause ] ^M00:07:56 All right. We'll go over the typical example of a swap function. ^M00:08:02 [ Pause ] ^M00:08:04 That's here. Oh. So this line, like, hint to that before is swap line is the function's prototype. So those are the sort of things that we'll see in header files like standard IO.H. We'll also see like struct definitions. We'll get to structs. We'll see hash define things. So, here in main, we declare variable X and variable Y, and then we print X, print Y. And now we want to swap X and Y. So ideally, after this swap line, X will have the value 1 and Y will have the value 0. They will have swap values. And I won't actually run it. But trust me when I say that this will not succeed. Looking at the actual swap function, we see it takes A and B, so we're passing X for A and Y for B. We then store A in a temporary variable, put B into A, and put the original A into B. So, why this doesn't work is it's important to remember that everything in C when you pass its way function it's always a copy of the thing being passed. And so here, what we're actually passing to a swap is a copy of the value 0 and the copy of the value 1. And so down in the swap function when we say A equals B, we're just modifying the copy of those values. We're not modifying the original X and Y. So here's where pointers become important. ^M00:09:37 [ Pause ] ^M00:09:50 So, here, notice the function prototype is changed. We now are passing int star A. So as soon as you see int star or char star, anything star, you know you're dealing with a pointer. And it's coming down here. We're no longer passing X and Y. We're passing ampersand X and ampersand Y. So ampersand, I usually read literarily as address of. So we're passing the address of X and we're passing the address of Y. And so--Oh, and it's--since X is an int, then when you get the address of an int, the type of that address is an int star. We had a char and--with an ampersand before it, then we would have a char star. So coming down into the swap function, again, this is going to take an int star and an int star. And here, it's unfortunately somewhat confusing that there are two uses for the star. The first use for the star is to declare something as a pointer type. So when you see int star B, you know that B is a pointer to an integer. When you do not see a type, like right here, when you say star A, we are de-referencing that pointer. So if B points to Y and A points to X, then star A is referencing the original X. And so temp is going to store the original value of X. Star A equals star B, we're going to go to the original value of X, like the original X and we're going to store there the original Y. And so, X is actually been changed now. And here, we're doing the same thing. We're going to Y and storing the original value of X. Questions? ^M00:11:41 [ Pause ] ^M00:11:43 OK. So, in Objective-C, a lot of this is going to be--you won't be needing to do as many explicit de-references. But it's important to remember that when you're passing these things that object themselves are pretty much like pointers. And so if like you're passing object to a function and in that function you modify the object, the original object will had been modified and we're going to see that. ^M00:12:08 [ Pause ] ^M00:12:15 And just for fun, I threw in the end that char star star is also an example of a pointer. It just happens to be a pointer that points to a pointer that points a char. So a good example of that is just our command line arguments, argv. So, ignoring the fact that it's bracket syntax, there are some--this isn't entirely true. But in a lot of scenarios, arrays and pointers are pretty much equivalent. So con char star argv bracket, we could have also said as con char star star argv, which makes sense since argv is an array of strings and we represent a string as a pointer to a single character. Questions? ^M00:13:04 [ Pause ] ^M00:13:13 OK. So, structs, so it'll be important to actually remember structs because you will still be dealing with them in Objective-C and a lot of the iOS code will be dealing with some structs. Unfortunately, it can be somewhat confusing 'cause you might forget when you're dealing with a struct versus an object since they are different. But let's look an example of using a struct. Remember, struct is pure C and objects are Objective-C. ^M00:13:43 [ Pause ] ^M00:13:46 [ Inaudible Remark ] ^M00:13:47 Yes. ^M00:13:48 [ Inaudible Remark ] ^M00:13:50 So you can. Once we get to Objective-C, you can, yes. It's--A struct is literarily just a wrapper for a--like a group of variables. So you're going to have a variable point to an object then you can store that variable in a struct just as well. Looking at a struct example that doesn't use objects. ^M00:14:17 [ Pause ] ^M00:14:21 We see here this typedef struct student. So the only reason for the typedef is so that--[inaudible] technically it's a student here. But the only reason for the typedef is so that whenever we want to declare a variable of this struct type, if we just do this, now we have to say, struct student X and struct student Y. So the typedef just saves us that. And now I can just say struct student--or now we can just say student X and student Y. So what is inside of this struct? We have an age and we have a name. And so, these are exactly what structs will look like in Objective-C. And coming down here, we see we declare a variable of this struct type, Alice, and we're going to use .notation to access the fields in that struck. So, Alice.age equals 20 and Alice.name equals Alice. And we could do the same thing, we just declare Bob and that's pretty much like everything about Structs that you will need. So, questions? Oh, and then if you want, look at degree [phonetic] function. Up here we are storing inside of Bob at age 21 and down here we are accessing Bob.age. OK. Next, we will also have enums which are somewhat more important in Objective-C than they were in--perhaps you've used in regular C since there's a lot of the--a lot of code you'll be working with uses a lot of enums. So, what does an enum look like? So, it's like a struct and again we're just using typedef so that when we want to declare a variable of this enum type we don't have to say enum genders X and enum genders Y. Thanks to the typedef you're going to say genders X and genders Y. So, enums aren't strictly necessary. We could instead do hash define female as 0 and hash define male as 1. And hash define just declares this to be a constant. So right now, if I got rid of this, the two programs will be almost equivalent except for the fact that I just got rid of the genders type. So, why do we prefer enums over these hash defines? Because if I add a whole bunch of hash defines something two, something three, something four and then I decided to like, reorder them. Then I would have to like change the numbers on all the rest of them and also it's just a convenient that I don't have to explicitly list the numbers on all these things. Once we get to Objective-C and I think more specifically Xcode, there's also some--well, it's coming down here. We see that we have changed this struct to now not--or now it takes a name and a gender. So, Alice is going to be--is going to be given the name Alice and it's going to be given the gender female. So, it's important to remember in C and also Objective-C that there is no enforcement of the gender's type. So, I am just as easily able to put a hundred underneath the hood and enum is literally just an integer. So, even though a hundred is not a valid genders, it will let me do this. But in Xcode, generally it will--it will yell at you like visually if you're using things that aren't correct enum types. So, you'll wan to use these enums correctly. And that's pretty much it for enums. Questions? ^M00:18:21 [ Pause ] ^M00:18:24 OK. So then, arrays, regular C arrays are still going to work in Objective-C. You're also going to see that there are these new array classes that you're probably going to want to get used to. So, you might not be using them that much. Just to look at an example of using the arrays. ^M00:18:50 [ Pause ] ^M00:18:55 So, here we declare the variable int 10. We print enter number of exams and then scanf is just a way of grabbing input from the keyboard. So here we are scanf'ing for some integer, this percent D carries over from printdef. It's looking for an integer. And why do we need to--why do we need to pass ampersand N and not just N? Why would this never work? ^M00:19:24 [ Pause ] ^M00:19:29 [ Inaudible Remark ] ^M00:19:30 Yeah. So inside of this scanf function, just like we saw before the swap function, ideally after this point in time N equals whatever number I type at the keyboard. So, scanf needs to actually change this N. Scanf can't change that without a pointer to that N, without having the address of that N. Otherwise, if I just did this and we'll first do in compile. ^M00:20:00 But assuming it did accept that, it would just try to set the local variable N to the keyboard entered value and this N would remain unchanged. So, we need to pass the address. Here we are declaring an array and that array is going to be of size N. So we're going to have N integers. And this is all going on the stack so far. And then we're iterating over the N values entering a grade into each individual spot in the array. So really, this program is going to behave like how many grades you want to enter? Three. What is the first grade? What is the second grade? What is the third grade? So, you enter each grade. And also we have to--So grades I is the Ith position in the array and then we also need to pass that by reference. We need to pass the pointer to grades I for the same reason that we needed to pass the pointer to N. ^M00:21:04 [ Pause ] ^M00:21:06 Questions? ^M00:21:08 [ Pause ] ^M00:21:21 OK. So, memory management. It's one of the bigger problems in C and for the most part, you are going to have to deal with it in Objective-C. There are some small things you'll have to think about and we'll get to that next week. But the malloc and free stuff that you're used to, you don't really have to deal with. So, remember that we have our stack and our heap. And so all of our local variables are always stored on the stack. And this means, let's say I call some function and it needs to like return some array to the function that called it. It can't just return--it can't just return an array on the stack and return it, because once the function returns that array is gone. That's the point of it being a local variable. The array is gone. So, malloc, what that does, is allocate space on the heap and the stuff that out--that's allocated on the heap survives past whenever the function happens to end, whenever that variable happens to go out of scope. And so what malloc and free are like manual memory management versus the automatic memory management of local variables. And something to keep in mind is that pretty much all objects are going to be like this. All objects are going to pretty much be malloc. They're going to go on the heap. And so they are going to continue existing after the scope of that variable ends. But thanks to the new iOS Objective-C features, you don't really have to think about freeing that memory. So we'll see why that's really useful. ^M00:23:06 [ Inaudible Remark ] ^M00:23:08 Yes. So, the new--it's ARC, A-R-C is Automatic Reference Counting and it will automatically collect these objects for you. That was not the case two or three years ago. Yeah? ^M00:23:21 [ Inaudible Remark ] ^M00:23:25 When you don't want to use ARC? So, the only thing I could really think of is like if you wanted to be really explicit about the--like you want to fine-tune your program, overly optimize it to make it like run better. But that's probably not the beast use of your time. It's--You are already using Objective-C which there are a lot of things that that's not doing in the most optimized way possible. So, pretty much any app nowadays is going to use ARC. ^M00:24:05 [ Inaudible Remark ] ^M00:24:09 Oh, so an example-- ^M00:24:12 [ Inaudible Remark ] ^M00:24:16 It probably would. But it's not really worth even trying to optimize your app for that. ^M00:24:25 [ Inaudible Remark ] ^M00:24:26 Yeah. ^M00:24:27 [ Inaudible Remark ] ^M00:24:35 No, it will not. You pretty much shouldn't be malloc'ing. I actually wonder, I'm not a hundred percent sure, but I imagine it's already taking very strict control of what the heap looks like. And so, if you start malloc'ing things on top of what it's trying to do with the heap, it might screw it up but I'm not sure. You won't need to malloc. OK. Objective-C. So C questions before we move on to Objective-C stuff. Yeah. ^M00:25:06 [ Inaudible Remark ] ^M00:25:08 Oh. So that's--Well, in C you would need to use free. So anything you malloc, at some point during the life of your program, you should also free. In Objective-C, that's the thing so things are going to be somewhat automatically allocated for you and they will be automatically de-allocated for you as long as you adhere to some things we'll see next week. OK. Any other questions about C before some Objective-C stuff? OK. So, from our Hello World in C to our Hello World in Objective-C, there aren't too many changes. You'll see that it looks a lot like C in a lot of ways. Unfortunately, the first word has literally changed. So what do you think the difference is between include--like we used to say hash include, now we say hash import. So what do you think the difference is there? ^M00:26:06 [ Pause ] ^M00:26:09 So hash import is smarter than hash include and that it will only import something exactly once. And so, this used to be an issue with hash includes like if you hash include a header file twice and you don't take special precautions in that header file, then you might duplicate some definitions of things and it won't compile. Hash import, no matter how--if I said hash import foundation dot--or like if I just copy and paste this line, the second line wouldn't do anything. So, hash import just going to be more efficient in that. And the--another thing that looks somewhat different is this @autoreleasepool. So that's going to be something we deal with next week. That has to do with automatic memory management. And the one thing to note and we'll also see it in front of the Hello World is @ is a very Objective-C thing. So like if you see code and you see an at symbol, you might be able to reason that it is Objective-C 'cause you're going to see this all over the place. In case of the Hello World, so normally we would see just like string hello world by putting the at symbol in front of it, we are making it an Objective-C type string. More explicitly we are making it an NS string. So we're going to see that in a couple of other places. But now this--this at hello world is an object that we are passing to the NS log function. Let's actually run that. ^M00:27:46 [ Pause ] ^M00:27:55 So what is the ridiculous--and so you will pretty much never need to compile at the command line. Because once we get into Xcode, that's going to pretty much be everything you need. But here, we have compiled that program. It's exactly the same as the one that we saw in the slide. And running it, we see something that looks like this. So, we see the date, we see the time, we see main and then this happens to be the process ID and then something called the "Mac Port" [phonetic] that you don't have to care about at all, and then the actual thing that we NSLogged. So, this is what NSLog does. You will probably be using NSLog pretty frequently in your programs to debug things. In actual released apps, you probably want to get rid of your NSLogs or have them wrapped in, like, debug type statements. Since--Once you're on an iPhone, you pretty much don't have access to anything that is NSLogged. I think theoretically, you can like plug in your iPhones to your computer and see what was NSLogged. But that's rare. Like, anything released to the App Store isn't going to have any of those. ^M00:29:14 [ Pause ] ^M00:29:22 OK. So this is our first exposure to an object, but it doesn't really feel like an object 'cause we're pretty much putting that sign in front of it. That's technically shorthand for creating a string object. And we--I think we'll see the longhand later or at least see many other objects that we're going to be creating. So, use those signs that just says everything so far has been the command line. Everything can be done at the command line. You probably won't want to do things at the command line. So, Xcode is pretty--pretty comprehensive on all the things Objective-C in iOS. ^M00:30:02 You should be able to get it for free and we aren't really going to go into the details of what all these different places in Xcode are. It's pretty overwhelming the first time you see it. The only things we're going to be using today, like--it's going to look like three of them. So, we're not going to be using utility area. The debug area is where we're going to use to see where NSLog things are going to be printing. The editor area is where we're going to see our code. And navigator area, we're just going to see our files. And it also contains all this debuggings, important stuff, but we're not going to go into that. So, you could--if you have an iOS device and you want to actually install these apps to your iOS device, this was discussed last week. But you need a developer account. So through us, you can get a free account. But you are not able to actually put the things on the App Store. So if you want to put things on the App Store, you will want to get your own accounts which is 99 dollars per yourself and I think like 2.99 for a company or something. So, you're going to look up a lot more there and this will be put online later. So, the new data types in Objective-C, there is pretty much only two big primitive data types that you need to care about, so BOOL and ID. So, a BOOL is like a BOOL in every other language. Unfortunately, it is not true and false. It is yes and no. So you're going to be seeing a lot of capital, yes's and capital no's as in your programs. I think the reason for that is once we started seeing functions, the way the functions are awarded, it's kind of like--and do you want this? Yes. And do you want this? No. ID. So, if you're more familiar with C and you know what void star is, ID is sort of like that but for objects. ID just sort of represents like a generic object. You don't know what the type of the object is, but you know that this thing is an object. And nil is sort of the counter point--counterpart of null. So nil represents a non-existing object but it has some special properties. Questions? OK. So here are some data types that if you saw when we hash imported foundation slash foundation dot H which pretty much everything you're going to be doing is going to do. We also get some of these data types and as integer and as point and as rect. These are not objects and this can be somewhat confusing because it can be somewhat difficult to differentiate between objects and just these typedef things. So, they exist for various, like, legacy reasons and so, like, NSInteger exist as sort of this weird bridge between 32 bit and 64 bit and pretty much use it whenever like--when you're looking at documentation and you see that this function returns an NSInteger, use an NSInteger variable. So, none of these are object types. Now, just a quick discussion about what classes and objects are in case you don't have any object-oriented experience. So, we're going to be defining classes today. And a class in--It's going to be similar in Objective-C to other languages you've seen. A class is going to define methods and variables and it's pretty much a blueprint that then objects, you're going to create from those classes. So a class is going to say like any object of this class should have these variables and these methods. And then it's on those objects that--or in those objects, you're actually going to have those variables. So, you have a single class and many, many objects can come from that single class. It's also important to remember that in object-oriented programming, classes, you're going to have this hierarchical relationship that we're going to be seeing. So like if I define--Well, in Java you might have seen like the objectClass. In Objective-C, the equivalent is NSObject. So, everything, almost everything in some way inherits from this NSObject class. And so--so if I defined some class, person that inherits from NSObject, then I might define another class, student that inherits from a person and then I might define some other class, 8th grader that inherits from student. So, remember that these classes have these hierarchical relationships. And this is important when you're looking through the documentation because if I look at some random--like, if I look at the Apple documentation for the 8th grader class and it shows me, like, the method spelling homework. You might think that's the only method it has, but it has a lot more methods than that because it's also inherits all of the methods from all of his parent classes. So, you need to look through the hierarchy to know all the methods everything has. Question? OK. So, .h files. Unfortunately, the interface keyword is somewhat different from what you might think of as like a Java interface and some other languages interfaces. It's still similar and that you're going to be defining like you're just going to list the prototypes of the methods that you want to be in this class. But we'll see later this thing protocols and those are going to be more like the interfaces you're used to in other languages. So in .h files, we see--we have this @interface, and so @ as usual telling us it's Objective-C. So @interface and this class is going to be called foo and then this colon indicates the class that we are inheriting from it. So our parent is going to be NSObject. And then this ugly syntax where we put curly braces and then instance variables go in the curly braces. And then underneath the curly braces, we declare all the methods that this class needs to define. And we'll see plenty examples of those. And then getting into .m files. So pretty much every .m files is going to have its corresponding .h file. Inside of the .m file, we give the implementation of these things. And so here we're going to give the implementation of foo and actually define all the methods that in this .h file we said we would define. OK. So we'll look at an example. And this time we'll do it in the next code. Actually. ^M00:37:14 [ Pause ] ^M00:37:24 All right. So, here we see on this left side, we have our files. I'm going to get rid of this right side 'cause we don't need it now. Up in the--or down at the bottom, we're going to have our NSLogs stuff down here. So looking through these files--I'm not going to be able to do that. So looking to these files and we see--we have a main function. We have the same AutoReleasePool thing that you can ignore for now. And then we're going to have these student star Alice. So, student we see over here is going to be an object. We have .h file and .m file for it. We'll look at those in a second. Student star, so I guess I'll go into that. Ignore this for a second. So, just student star Alice, we're going to allocate the student. So this is sort of like malloc. So, we're making broom for the student. And then apparently, we have some age field and some name field. Let's actually look at it. So here's student.h. And we have interface student, it's inheriting from NSObject. And here we see this @public keyword. This tells us that everything underneath that--all the variables underneath this word are going to be public instance variables. There's also app protected and app private. So private, no other class is going to be able to see these variables and protected any class that is a subclass of this class is going to be able to access these variables. So you won't need to deal with those too much. Generally, you want to make the access to these variables as tight as possible. So like if the variables can be private, make them private. So here, the instance variables we have are age and name which is an NSStrings star. And we see since there are no methods defined down here, that means that, well, let's look at it student.m doesn't need define any methods. Yes? ^M00:39:35 [ Inaudible Remark ] ^M00:39:38 Why do we use what? ^M00:39:41 [ Inaudible Remark ] ^M00:39:44 Oh, so, we could use string or just char star like a regular C type string, but in Objective-C, you're going to be passing around these NSStrings a lot. So you're probably going to want this thing to be an NSString. ^M00:40:00 Like when we want to actually print this, we're going to need print an NSString. We can't--Oh, when we want to NSLog something, we need to NSLog objects. So we're going to need to pass it in NSString. We can't pass it a char star. We would have to change that char star to an NSString. >> But we also got NSInteger [inaudible]. >> Yeah. So, NSInteger is--this is where it's--NSInteger is pretty much going to be just a typedef for regular int or possible long. This is not an object type. This is not a class. This is just like typedef, NSInteger, int. So, this why like--these aren't that helpful unless you see that a function in the documentation is returning an NSInteger. And then you should use NSIntegers. ^M00:40:57 [ Inaudible Remark ] ^M00:41:04 Yes. So that's the unfortunate thing. You got pretty--like the primitive ones are these NS--well, actually no, I can even say that. There are some complicated ones that are primitive and I wish they had done something to differentiate better, but they didn't. and let's change back to NS, but it shouldn't change anything. So, it mean--So we are now accessing this. So student star Alice is an object. That object has an age field and a name field and we are accessing those and setting the age field to 20 and we're setting the name field to be this NSString Alice. Note that this would not succeed without the @ because now it's not an NSString and it yells at us appropriately. And in case you're curious, this arrow syntax, it comes more from C, come--the next example that I gave you, you will not be using this arrow syntax. But what it is, is--so, we're treating Alice sort of as like a struct. And so, we are de-referencing that struct and then accessing the age field inside of that struck. So, arrow is equivalent to star Alice dot. It's--This to just say very disgusting syntax since, that's why they give us arrow. Arrow just means, here is a pointer to a struct/object and go to that object and change this field at that object. But you will not be using arrows on objects ever. So, this is a pretty bad example, but this is our intro example. Do the same thing with Bob, we allocate and we give him an age, we give him a name. And then greet [phonetic] down here. We're going to NSLog and we see NSLog and we need to pass NSLog and NSString as its first argument. And so we see our normal percent D over here and as age is just as we saw in the student.h file, as age is just an int. And so that's fine. And as name was an NSString. And so, the NSLog version of like percent S for NSStrings is going to be this percent @. So, that is the flag for printing NSStrings. Actually running this, on top, hitting build or run. I forgot the shortcut for it. And down here we see the NSLog output. Hello Alice, you're 20. Hi Bob, you're 21. Questions on this simple example because it's going to be changing pretty substantially in the next example? ^M00:44:18 [ Inaudible Remark ] ^M00:44:19 Yeah. So, this is also what I kind of pause at before 'cause I don't want to say quite yet. Student star, student is really like--Alice is the object but like pretty much read student star--don't read that as a pointer to a student, just take student star to be like the type of the object. So, you will never really be dealing with a student Alice. You will always be dealing with a student star Alice. And in the next sample, going to students to-- ^M00:45:01 [ Pause ] ^M00:45:07 [ Inaudible Remark ] ^M00:45:15 No, not really. ^M00:45:17 [ Pause ] ^M00:45:21 OK. So, in this example, let's look at .h first. So now, this is the same, it's inheriting from NSObject. We have changed this. We're no longer saying int age and NSString name. We're saying underscore age and underscore name. And that is a convention that in the past it used just to be a convention and now it's a convention that actually mean something. So you're going to want to pretty much always have these instance variables be underscored. And now, here we're getting to these strange looking method things. So, let's actually go back to slides for a second. ^M00:46:01 [ Pause ] ^M00:46:04 [ Inaudible Remark ] ^M00:46:06 We'll see in a second why we want the underscores and I quite gotten there yet. OK. So instance variables, we saw, we know them @protected, @private, @public. And it's somewhat messy. But like when I said @public, everything beneath the @public would be public. But then if I switch to--like if I @public int X and @private int Y. Y would be private 'cause it's underneath the private. OK. So, first let's look at this. So, messages. In other object-orientated languages, you don't really--well, some you do. But Java, you don't. So, messages are going to be the way that we invoke methods on objects and classes. So here, this square bracket syntax is what you're going to be using to send messages. And here we're saying, the student class has a method called "alloc." And so, send to the student class that method. Invoke that method. And then that is supposed to return a student star. And so this alloc is going to be pretty much everywhere. You--Whenever you need to allocate an object, you need to do some sort of alloc. Sometimes, there is like alloc, sometimes there are some other alloc type function you might be using, but you're almost always going to be alloc'ing these things. So, here--So there are two different types of methods like there are in other object-oriented languages. So we have instance methods and class methods. And so, the way we're going to differentiate between those is all the way on the left side, you see we have this minus sign. So, if we have a minus sign that means the method is going to be an instance method. And if we have a plus sign that means that it's going to be a class method. And an instance method is something that you actually need an object to use the method and a class method is something where you don't need an object to use the method. So going back to here, the fact that we're calling alloc on the student class tells us that alloc is a class method because we don't actually need a student to allocate a student. That'd be pretty flawed if we couldn't actually get a student without having a student. ^M00:48:28 [ Inaudible Remark ] ^M00:48:30 Yes. So, yeah. The static keyword from Java is the equivalent of plus. So the syntax for these things, we see all the way in the left is going to go plus or minus always. And then we're going to have the return type of the method. So here we have void, int, void. Then after return type, we have the name of the method. And so we have the name init and we the name age. And then technically the name of the last method is going to be set age colon. We'll see why. But this here--this age is what we're just going to call that variable. And this is the type of that variable. So, this method isn't going to return anything. It's called set age colon and we would pass it some integer. ^M00:49:29 [ Pause ] ^M00:49:33 So, sending those messages, we see that student--we're using lowercase student, so the student over here, the student object, since these are instance methods, we need to send these messages to objects. So we send the init message to student. We send the age message to student. And then we sent set age with the parameter 20, with the argument 20. Questions? ^M00:50:02 [ Inaudible Remark ] ^M00:50:12 What do you mean? ^M00:50:15 [ Inaudible Remark ] ^M00:50:20 >> Yes. That is how you should call it. ^M00:50:25 [ Inaudible Remark ] ^M00:50:28 Could you call as what? >> Like I would in C. >> How would you call it in C? >> I mean is that like I would say C and then like that? >> Oh err--so no. This is why the previous example is something that was bad. You should very barely be differencing objects. I almost want to say never difference objects. And so, the arrow operator is n implicit difference. And so init is also somewhat different from setting the fields of the object. And another reason why the previous example was bad, you always--you never want to deal with an object that was allocated but not initialized. So, even though the student objects, and we'll see in the next example how--how originally just had like student alloc and I did Alice arrow age. I shouldn't have done that. I should have done student alloc init. So always initialize your objects and then I could access those fields. But then on top of that, I shouldn't be accessing those fields using arrows, I should be sending messages. And so we'll see that in the next example, the right way of doing that. And then we'll see that there are like 10 new or right ways of doing it. So selectors--pretty much an alternative name for method, so alloc, init age and setAge colon. Remember the colon is part of the name? Once we see multiple argument functions, we'll see that there will be multiple callings in the name. So, all of those are just selectors and we'll see why that's relevant later. And let's look at that example now. So student two, OK. So, here we have said int underscore age and underscore name. And now we have for methods and this is like the getters and setters of Java that you might be used to. We have two methods, one called age and another called setAge that the first one is going to get the age of the thing. And the second one we're going to use to set the age. And then similarly down here, we have name and setName, the first we're going to use to retrieve the name and the second we're going to use to set the name. And these are important names both by convention and we'll see things that help us later where in other languages you might say like getName and setName. Here, the convention is just to say name. Do not say getName. Questions? OK, so looking at the implementation, we must be implementing these for methods. And so, notice, they are all instance methods, they are all minus. And age, we'll just going to return underscore age. And setAge, we're going to set underscore age. So we're going to set our instance variable age to the pass in argument age. We're going to return underscore name and we're going to set, and this one is somewhat interesting. So, we're going to set our instance variable underscore name to name copy. So, we know that this in fact is how we're going to send message to objects. Name is in NSString object. And so, apparently and you can look it up--you can look in the documentation to verify this. Apparently name or NSString has an instance method called Copy that is going to return a copy of this NSString. And why do you think we want a copy of the NSString instead of just saying underscore name equals name? ^M00:54:27 [ Pause ] ^M00:54:34 Yeah. >> Well because it's an object, it should be modifying the pointers of that object so it would be modifying the initial objects. >> Yeah, so it isn't--well actually, so, if we did not make a copy of the name, it isn't a thread that we are going to modify that NSString since we don't have any methods for modifying that NSString. I guess we--if we went around the proper method protocol, we would be doing things. We'll see why we should never be modifying name. But it's possible that the NSString that was passed to us @Bob or something is that--that could later be changed. And so if that is changed then if we just do this, then we are also going to--the name within this object will have been changed. So we want to copy Bob for ourselves in case if Bob has ever changed, we don't want to be changed. ^M00:55:30 [ Pause ] ^M00:55:33 OK, so looking at main.m [phonetic], now this is the better way of doing this. This is like appropriate objective-C. We can see that there are more and more better ways but this is at least like not bad. So, we are appropriately initting and notice that we are allowed to like nests these things. So, we could if we wanted do student alloc and then Alice equals Alice init, but we are allowed to nests these calls. OK and now we are, instead of directly doing Alice arrow age equals 20 which is bad. We are saying Alice setAge to 20. We are sending the message setAge with the argument in 20 to Alice and we're setting the name to Alice and similarly with Bob. And then what greet [phonetic] is going to do is use this S name and S age. We're going to send those getter methods to get getter messages to get the appropriate instance variables. Yeah. ^M00:56:53 [ Inaudible Remark ] ^M00:56:59 Oh so, the only reason we can do that here is because student alloc happens to return the student object. And so we are then using that student object and initting it. And that also returns the initialized student object. SetAge doesn't return this student object. If we do we could actually do that we can do like instead of void, we can have it return the student object. ^M00:57:25 [ Pause ] ^M00:57:31 >> And then this is going to get into return self. Self is going to be your keyword here. We'll see it later. ^M00:57:37 [ Pause ] ^M00:57:43 [ Inaudible Remark ] ^M00:57:52 So here, are you saying why should we need-- ^M00:57:57 [ Inaudible Remark ] ^M00:58:01 So this is that you never pass but--you never pass objects by value. You never handle objects as explicit values. You're always going to go through a pointer to the object which is why I say pretty--think of like NSString star as the object not a pointer to the object. Think of it as the object. Except that if you modify it, then it's going to be modified because it's a reference. OK, so now we're returning self which is going to allow us to do that nested. Now we're free to do Alice setAge 20, setName Alice. ^M00:58:41 [ Pause ] ^M00:58:45 [ Inaudible Remark ] ^M00:58:48 We--not yet. The next example we'll be able to. Just to point out one other thing that you might see in like documentation or like example online or stuff. So alloc init is such an incredibly common thing like you alloc init--you might be doing some different initializer. There are different initializers but using alloc and init is so common that there's actually a shortcut-- ^M00:59:17 [ Pause ] ^M00:59:20 --New, and so, new is going to sort of--or new is going to first allocate and then initialize. So that does it in one step. There are sort of--well, this is the first of three religious wars you'll hear today about objective-C that there are a lot of people who will say new is a perfectly fine thing, and there are lot of people who will say you should absolutely never say new. So, we don't care which you use, whether you want to explicitly allocate and initialize or whatever. ^M00:59:54 [ Pause ] ^M00:59:56 OK? Questions on any of that? Yes? ^M01:00:01 >> So does allocate initially reserve space on the key for the object and then setting on the instance variables on that? >> Yeah, it is--potentially other things than setting instance variables. If you wanted, you're going to find the initialization method that like counts the number of objects of this type that had been initialized. But you should never handle an uninitialized object. ^M01:00:26 [ Pause ] ^M01:00:29 OK? So then this is going to be the next example that we're going to want to use but let's just look at the slide first. So, Property so--and this is going to be what we're going to use to enable us to use .syntax. We can somewhat ignore a lot of these keywords for now. These assign, copy, strong, weak are things we're going to deal with next week. Strong and weak in particular are pretty much the only things you really need to think about under ARC. Those are memory management difficulties that if you got those wrong, you can still leak things. But it's not too bad. It's especially better than needing to keep track of everything. Atomic and nonatomic are a different pair of things that we'll get into and we don't mean readwrite. We will talk about today. So @property, new thing. So look at the example. ^M01:01:32 [ Pause ] ^M01:01:39 Student-free. ^M01:01:41 [ Pause ] ^M01:01:45 OK. So looking at student.h, the only thing that is changed is that we have added these two lines. So, we have SetAppProperty and from each of those groups that we saw in the--on that property slide, we are picking a sign from the first group, nonatomic come in second group, and readwrite from the third group. And then we're saying that this instance variable is called int age. So, assign again, you can ignore nonatomic. This is just saying that like you can assume that we're not dealing with any multi-threaded type messiness here. You don't have to deal with the overhead of making sure that whenever we modify this age instance field that you don't have to deal with making sure it's atomic. So atomic just means like it happens instantaneously. We don't have to deal with that. So, and readwrite, this is probably or in this class you're pretty much only going to using nonatomic. Readwrite is one that if it's readwrite then this property is expecting a setter and a getter. If it's read-only, it's expecting just a getter. So since we want to be able to both write to age and get the age, then we say its readwrite and some it will lead for name. OK, so then these are the same. Back in student.m we see the same. But looking at main.m, the fact that these are now properties allows us to say Alice.age equals 20 and Alice.name equals @Alice. So what do property does for us is says that since we said there is a property called age then Alice.age is by the conventions that are now going to be like something you should absolutely follow, Alice.age is underneath the hood going to be translated to Alice setAge 20. And this is going to be Alice.name @Alice. So this is what properties have done for us. It's allowed us to access and set instance variables using .notation. Instead of having to go through this set name and setAge method or message passing. It's somewhat important and yet at the same time not really that important to remember that we are going through the overhead of a message pass. So it's not like in regular C, this is not a struct, so you would not be able to use .notation on a pointer to a struct. This is an object, this .notation is calling a method and so there's some overhead to that but again its Objective-C, let the compiler handler--let the compiler handle any optimizations. Don't really worry about the overhead of message passings. Then down here at greet, we see s.name and s.age which are equivalent to just S name and S age. And so this is why I said before, you should follow the convention that like the getter is just called name and not getname, because s.name is going to expect the getter to be called name. And if it's not, you're not going to be able to use the property as expected. ^M01:05:29 [ Inaudible Remark ] ^M01:05:37 Wait till the next example. [laughs] Yeah. ^M01:05:42 [ Inaudible Remark ] ^M01:05:50 I changed that. They should always have it. Yeah. [Inaudible Remark] So the reason for this is that NSObject's init method, so init is inherited from NSObject. And we see that Student is directly inheriting from NSObject and so because the init method of NSObject does nothing, then there is no difference between Student alloc and Student alloc init, those two things are going to be the same. But you should always handle initialized object if--I doubt NSObject would do this, but if someday NSObject changes initialize method to now keep track of something, then this code will break because you did not initialize that object. Or alternatively, if inside of Student, I decide to overrride the init method and have it do something, define my own init method, we'll actually see examples of that later. But if I were to define my own init method, then all of a sudden, everything in main.m would stop working because it did not initialize the Students. So always--even if you know you're inheriting from NSObject, still initialize it. Even if it's because someone later on coming around reading your code is going to be like, "Wait, this isn't initialized," now, they have to go check to make sure that it--the initialization isn't actually going to do anything, it's always initialized. ^M01:07:22 [ Pause ] ^M01:07:26 So one last. OK. Any other questions? ^M01:07:32 [ Pause ] ^M01:07:35 OK. Then here. OK. So synthesize, this is what in the past was used to do exactly what you just said, that getting rid of the getters and setters. So, what--let's look at Student 4. ^M01:08:03 [ Pause ] ^M01:08:15 So we have gotten rid of the explicit declarations of the setters and getters from here, just deleted them. They were redundant to begin with. And Student--or student.m, we've now gotten rid of the implementations of those things. In the past, we used init do like @synthesize age equals underscore age messiness. The reason for that is because the compiler didn't use to be smart enough to recognize that if there's a property in here, then it should automatically be in here. Now, it is smart enough. So now, the property is enough to say that we want an instance variable called, we're actually using the defaults, and this is again why we come back to underscore, the defaults of this line is, we want an instance variable called underscore age that has a setter called setAge and a setter--a getter called age. And that setter and getter is going to be implemented using these particular semantics but you don't have to worry about assign and nonatomic yet. This also means that before, even though we had set assign, and nonatomic, and readwrite, you are allowed to override those. And so before in the previous example when we had explicitly defined the setAge, setAge was not necessarily following these semantics. It happened to be because that's how we implement it. We didn't implement it carrying about whether it was multithreaded and all that stuff. So you are allowed to override these behaviors. I actually think Student 5 might go into that. ^M01:10:14 [ Pause ] ^M01:10:18 So Student 5, looking at student.h, again, we still have age and name. Now, in student.m, we still do not synthesize but we just happen to decide to overwrite the setName method. This was David's example of if the name happens to be David, then change it to Dummy, otherwise, do the original behavior. So here, we have overwritten what the default setting would do if we just did copy nonatomic. But, if we also decide that we wanted to-- ^M01:11:03 [ Pause ] ^M01:11:14 If we decided that we wanted to override the getter, and say return name, now, because of the way things are, we do need to explicitly synthesize. So, now, we would need to say synthesize name equals underscore name. And those should go away. All right. It's only if you happen to be overriding both the getter and the setter that we need to synthesize the variable again. Otherwise, it wouldn't know that this underscore name variable exists. This behavior is because of some backwards compatibility issues but it's the way it is. ^M01:11:58 [ Inaudible Remark ] ^M01:12:03 But if you use property and you say readwrite, if it is a readwrite property, the getter is--getters and setters are automatically defined before you unless you decide to override them. And if you override them both, then you need to synthesize again, because otherwise it doesn't know about that instance variable. It's like looking at student.h, we see property age and property name, we don't see anything about underscore age and underscore name, and that's part of the reason why we need to synthesize. It's messy but rarely are you going to be overriding both the getter and the setter anyway. You might be overriding them in--if you are like trying to debug something and you add NSLog to both the getter and the setter, in which case, remember that now, you're going to need to synthesize or self, it'll [inaudible] you. Questions? ^M01:12:59 [ Inaudible Remark ] ^M01:13:05 Yeah. See? It--well, if I get rid of the assign, now, I'm going to get a bunch of errors. If I now get rid of this setter, I don't have any errors anymore, because as long as I only override one of them, it's fine. It's also important just to recognize synthesize because you're going to see it in a lot of prior examples, like a lot of online things you find will use synthesize, 'cause it's a relatively new thing. But you don't need to use it. OK. ^M01:13:42 [ Pause ] ^M01:13:48 OK. So, init methods. So up till now, we just used init. Remember, you should always initialize something but you don't need to initialize it with just init. You can define your own initialization methods. And if you look at--well, when you're actually doing iOS, you're going to be dealing with a bunch of other initialization methods. But the convention is that the initialization methods are always going to start with lower case init, and then, the--so, reading this method, we have an instance method 'cause it's a dash. It's going to return an ID, so this is also convention. We know that it is necessarily returning a Student star, and remember that ID is just sort of like a catch all for all objects. The convention for initialization methods is that they return ID. Then the--this is pretty much the convention too that we have initWithName: and we pass it a name. And notice now, we are passing a second argument, so space andAge:age. So the name of this method is initWithName:andAge:. That name and age are arguments. Those are not part of the name of method. So, we already see how these names can get pretty long. Believe me when I say that there are method names that are like four times longer than this in iOS dealings that you will be using. So, one other--I don't know. Questions. [Inaudible Remark] Yes. It's very similar to void star except it's dealing with objects instead of general pointers. And we'll see ID in other places too. And it's also similar to voidstar and that automatic casting happens. [Inaudible Remark] This whole thing? OK. So, we have instance method. It is returning an ID so that's just the way it is. If you wanted, you could say Student star, but you shouldn't--you should say ID because any initialization method pretty much returns ID, then the convention is that you're going to init and then with is also pretty much the convention. The--any colon--you can count the colons to determine the number of arguments to your function. So here we see two colons. That means we know they're going to be two arguments. The first argument is called name, and a subtype NSString star. The second argument is called age, and a subtype int. So, when we want to actually call this function, we might say like, well, first, we allocate a Student and then we say, Student initWithName:@bob andAge:21, and we'll see an example of that in another Students 4 or 5 or whatever. ^M01:17:03 [ Inaudible Remark ] ^M01:17:16 So, the answer is no, but that should never be the case because if the variables are different, this naming scheme should be different. This is how you name methods in like--all method names are very long and explicit in Objective-C. And so, if we decided that instead, we wanted to just initialize with the name, then we would have initWithName method without the andAge. If we wanted to just do name, we would've initWithAge method without the andName or whatever. Yeah. ^M01:17:51 [ Inaudible Remark ] ^M01:17:55 That was a typo. That has been fixed. These will be uploaded at the end. There are some changes. Other questions. Yeah. ^M01:18:08 [ Inaudible Remark ] ^M01:18:13 Yeah. You would just put more with andGender, andYear and whatever. The number of colons specifies--in theory, we wouldn't--we don't need to say andAge like a valid method name is init, colon, colon which--because there are two colons, we expect there are going to be two arguments, and so we call it with like init:bob:20, but that's not what you should do in Objective-C, you should explicitly name all of your parameters. So, initWithName:whatever, andAge:whatever. ^M01:18:52 [ Inaudible Remark ] ^M01:18:58 You cannot by default pass in a dictionary or object or anything like that, this is pretty much the only way you can run it, unless you happened to define initialization method that like takes what we'll see later like in NSDictionary, but that's up to you to define such an initialization method. It's--but you pretty much should--this is the way it should be. And also, if you follow this convention, I'm pretty sure Xcode is going to give you some like--some more advanced tips in Auto Completion and stuff. The convention being like they should return ID, they should start with the four letters, init. And when someone is reading your code, they expect you to initialize something so they should see the four letters, init. OK. Looking at this example. ^M01:19:53 [ Pause ] ^M01:19:58 Six. OK. ^M01:20:02 [ Pause ] ^M01:20:11 OK. So, in student.h, we see we are now declaring a new method, exactly what we saw before. Now that we have said that we are using this method, we need to implement that method in the .m file. So, here, let's first look at the initWithName. So, this is a very common pattern. Whenever you define your own initializer, this is pretty much the pattern you want to take where the-- ^M01:20:43 [ Pause ] ^M01:20:50 --first, second--let's say this first. So, this is somewhat weird from other languages where like self is just sort of like a keyword. Here, self is a variable and you're assigning to that variable the result of initializing your super class. So, this is the part of the pattern that you pretty much always do. So, just because like--or I happened to inherit from NSObject which its initialization method does nothing, but imagine that it does do something. So, just because I know how I want to be initialized doesn't mean I know how my parent class wants to be initialized. So, you should always call your parent--initializer of parent class. So, the reason we assigned to self and do this whole if self equals super init thing is under some bizarre scenario where initializing the super class manages to return nil or something, like initialization went wrong, then we don't want to do these two things. As an example, maybe we just happened to define the initializer as like only five objects of this class type should ever be initialized. After five, it should just fail. And so--then when they tried to initialize, if it's after five, presumably this super init is going to fail and self will be nil and then will just return self. Yes? [Inaudible Remark] Yes. Yes, yes. Self, this are two things you see in languages, there is no this in Objective-C, they just call it self. It means like--it means this current object. So, when I say--when I have a Student, like I just allocated the Student and then I passed that Student the message initWithName, whatever, then self refers to that Student I just passed the message to. And so, similarly, self.age which is also equivalent to self setAge, age. So, self.age refers to this student. We want to set our own age instance variable to age. ^M01:23:09 [ Inaudible Remark ] ^M01:23:18 Which do you need spell out? Spell out. [Inaudible Remark] This? So, this gets into that--there should always be--and you can look up these exact words designated initializer. So, not really going to go into deep detail here, but, every class should have exactly one designated initializer. And this is, in other languages, you might see it as like you define one constructor, that sort of all other constructors that you have called. And so here, we decide that initWithName should be our designated initializer, which means that init needs to call our designated initializer. If we then defined a (id)initWithAge method, that should be int, then this must also call our designated initializer and we'll use the defaults above, beyond andAge, age. So, there should always be one initializer which is your designated initializer. And also, that designated initializer needs to call the designated initializer of your parent class. So, notice that init and initWithAge are not calling super init, it's only our designated initializer which is calling super init. So that's just--if you start to find your own initializer, just make sure you follow this convention and you can remember just googling designated initializer. And also notice that I should not do this. Why is it? I should not do this because this is not appropriately setting self. So, we want to set self to whatever that happens to return and then return self. ^M01:25:32 [ Pause ] ^M01:25:34 Questions? And then going back to main. Now, we see that all in one line we're allocating a student, initializing it with a name Alice and the age 20. >> So the things we're allowing is super-- >> In here? >> Yeah. >> So, imagine we are--go back to the example from a while ago where were have like NSObject and we have person, then we have student, then we've 8th grader. So, I want to define a new initialization method for 8th grader and I decide that to initialize it like say, it has an instant 8th graders. Let say kindergardener. So, kindergardener has an instance variable favorite color and so we decided that like the default initialize--the default value for that instance variable should be blue. So, we define an initializer that says, "That should be blue" except if we don't then call super init, super now refers to, if we are a kindergarderner, super refers to student. And so if we don't call super init then we're not initializing all these instance variables that happened to come from the student class, in the person class, in the NSObjects class. So, you should always initialize your superclass. Similar to like you should always initialize any object that you allocate, you should always initialize your superclass and these two methods happen to initialize the superclass by calling the designated initializer which initializes the superclass. But again, this pattern like this is the pattern for writing your own initializer. So, we should almost always copy and paste this and then like in these curly braces is where you set your instance variables or NSLog whenever it is you want an NSLog. ^M01:27:35 [ Inaudible Remark ] ^M01:27:37 >> Yeah. ^M01:27:38 [ Pause ] ^M01:27:47 'Cause there might be something in that superclass that is like essential for everything else to work. ^M01:27:53 [ Pause ] ^M01:28:04 Any other questions? ^M01:28:05 [ Inaudible Remark ] ^M01:28:12 >> Why does init with age not needed? Because it's calling init with name and age. It's calling this method which itself call super init, OK. ^M01:28:24 [ Pause ] ^M01:28:29 OK. We'll take the five minute break. OK. So, am I--am I now louder? So, now, talk about collections for just a second. The only ones we're going to see right now are these NSArray and NSMutableArray where NSArray is in MutableArray which pretty much means like one set exists. It is what it is. You can't change it. MutableArray is going to be useful and that we're going to be able to just keep adding things to it. NSDictionary and NSMutableDictionary, so those are going to be useful for like KeyValuePair type stuff, associative arrays, maps, whatever, hash tables, whatever you want to call them, that's what you're going to use those for. Set is just another example of the collection. NSArray is going to be the most commonly used and we're going to use it right here. So, looking at the next example. ^M01:29:26 [ Pause ] ^M01:29:38 OK. So, Student.h and Student.m haven't changed. It's main.m. Now, we're trying to do something interesting where we have a NSMutableArray of students and we're just allocate--allocating it and initting it. And then we want to insert into that array Alice and Bob. So we've done it in one line. If we wanted, we can do the same thing. We can do-- ^M01:30:05 [ Pause ] ^M01:30:26 So, the NSMutableArray class defines an instance method called AddObject that is just going to take some argument with type ID. And so since student star is an object type, that isn't appropriate ID. And then we're going to do that again with Bob. So you name this as an array where the first element is Alice and the second element is Bob. And then here is I referenced this a while ago that we have this for in syntax that we're able to use with collections. So this well also wok for dictionaries and sets. So for each student in this NSMutableArray we want to greet that student. So one thing that's somewhat important to remember is that everything inside of this array is just stored as an ID, like there is nothing enforcing that I only put students into this array. If I wanted, I can put a student and then NSString and then another student and then some UITableViewController that's it's up to you to enforce that everything is of the same type or if you don't want to enforce that you then just make sure it's makes sense. You know what you're doing, but like if I wanted I could say, this and this isn't going to work because NSString doesn't have a name and age instance variable, but it doesn't know what's inside of the students array. So for all the compiler knows, it is an NSString. This is where it can be somewhat dangerous dealing with ID and this is also why you might need to be dealing with casts. So, you might want some cast these return values to the appropriate things. Okay. So, questions on this iterating over an array? Yeah. ^M01:32:33 [ Inaudible Remark ] ^M01:32:35 So it's--how it's working underneath the hood is that this NSMutableArray class needs to define how to iterate over it. And so in this method that it's defining for how to iterate over it, it's saying that like, "I'm going to do it in this order." So it's saying that like index 0 is the first thing that should be return then index 1 then index 2. >> Is there any way for that to [inaudible] like- >> So, we'll see--I don't think there is to--directly to erase. We'll see though that protocols at the very least are ways to make IDs a little stronger. There are ways to make sure that these IDs are at least objects that conform to a specific interface. I don't think there's any generic type construct in the language. ^M01:33:35 [ Pause ] ^M01:33:39 Okay. ^M01:33:40 [ Pause ] ^M01:33:47 Okay. So that's the syntax we just saw and notice here we are saying for ID foo in bar and so we don't know what is inside a bar and so all we can really say is ID unless you happen to know what it really is. ^M01:34:02 [ Pause ] ^M01:34:06 Okay. So, categories is a--actually, let's ignore that for a second and let's do another example first. ^M01:34:14 [ Pause ] ^M01:34:17 Student 8. ^M01:34:19 [ Pause ] ^M01:34:27 Okay. So the point in this example is I've decided I don't want to print these things in just whatever order I happen to insert them into the array. I first want to sort the array and then I want to print out the sorted array. So, there are couple of ways we can do that. I inserted them in the order, RJ, Chris, Rob, David, and so, here by looking at the NSMutableArray documentation I see that it has a whole bunch of different ways of actually sorting things. One way is this sorted array using selector method. First, let's look at Student.h and Student.m. So, inside of Student.h, I have defined a new method called compare. It's returning this NSComparisonResult, and the only reason that's relevant is because this sorted array using selector method expects a method to be passed to it that returns an NSComparator result, whatever it is. So, this compare method is going to take another student and just compare ourself, our current student with that student. Looking at the implementation of that, I decided that I'm just going to compare it by name. So, I'm going to use self.name references the NSString that is my name and then I'm going to compare that like the NSString compare method, I'm going to use that to compare to the other students name. And because this compare method returns an NSComparisonResults that is an easy way of making sure that I return an NSComparisonResult. OK. So, now that I defined this method for students, I'm now going to say here that I'm going to sort the student's array using the selector compare. So this special syntax @selector, remember that methods and selectors are kind of like interchangeable words almost. So, I can't just say like this 'cause that's not really a valid syntax. I want to say that I want to use the method compare colon, and so to actually specify the method compare colon, I wrap it in this special selector keyboard. And so, what this sorted array using selector method is going to do is iterate over the student's array calling the compare method of each student to say like, OK, student 0 and student 1, how do you compare to each other? And then like depending on how they compare is going to determine whether student 0 belongs in front of or after student 1. So compare has to exist for everything in this student's array. And then let's just run it to make sure that's the case that this works. So we see a print Chris, David, RJ, Rob which is what we wanted. ^M01:37:38 [ Inaudible Remark ] ^M01:37:47 >> So how do you in here--and you can also decide that we just want to compare ages. This isn't quite right because they're ints and I'm not sure of what NSComparison looks like. It might just be like return Self.age less than other Student.age, or I guess maybe like if 1 is less than, I'm supposed to return 1. Or if they're equal, I return 0 or else negative 1. I'm not sure what NSComparison, what it was supposed to look like actually. So, another--let's go to here again. So, a useful syntax that we've already seen this useful shorthand for defining an NSString, that's blah, blah, blah with the @ sign in front of double quotes. Another useful syntax is an @ sign in front of brackets for shorthand for defining arrays, so and NSArrays. So now I've defined an array, an NS array with two objects, Hello and World, two NSStrings. And additional shorthand that's somewhat is @ in front of any number. So this defines the approach like NSString was the first one, NSArray was the second one. This defines an NSNumber with the value 42. And so, what may or may not work. What I'm going to show it right here. No, actually that won't work at all. So, I might be able to do init NSNumber alloc. I just want to save the sense of working at this point, init with int self.age. And then I want to compare that, now I have a compare method. Compare to another NSNumber should be NSNumber alloc init with int, other student, age. ^M01:40:09 [ Pause ] ^M01:40:12 OK. So questions on what I just did there. Yes. >> You didn't use the selector up here. >> So, I'm not using--here, I'm just defining the compare method. It's when I want to actually reference the compare method that in here I say the method I want to use is compare calling. And this is again like I said before, like the literal name of the thing includes the colon. So here I'm referencing the method compare colon and the definition of it, I don't need to use @selector. ^M01:40:45 [ Inaudible Remark ] ^M01:40:50 A method to a method, yeah. 'Cause if it were a function, I wouldn't need to use that selector. I could literally just use a function pointer but you don't need to deal with those here. There is some--there is probably some spacing error here. All right, 'cause I don't need this, whatever. That's the general idea. So, that's that. Questions before I move on to a similar idea? Yeah. ^M01:41:28 [ Inaudible Question ] ^M01:41:34 >> And just as--remember, it's like C where--it's like C where this, in order to get the prototype for this thing, I can literally just like copy this, paste it, put a semicolon at the end. So the prototype is just the first line of your definition of the function. OK. So, that's that and now we're going to students 9 'cause we're getting into categories which that's not very helpful so here, let's--OK. So, the idea behind categories is notice that in order to do what I just did, I needed to actively modify the student class which is fine because I'm the one who created the student class so it's fine for me to go into the student class and add a compare method. But, what if this class that I need to modify is not something I have access to? What if it's in some compiled library or it's one of the--one of the foundation classes or an iOS class. I need to add a method to it but I don't have access to the source code. So these are what categories are for therefore extending existing classes. And so, in Xcode you can actually do this like file new, file and then Category and then like walkthrough through the steps. And the default format of these categories, so remember, I'm working under the assumption that I don't have access to the student class. So the default format of these filenames are student which is the class that I'm extending, plus, and what I happen to call the category. So here, I am extending the student class with the category StudentCompare and this is just the syntax that you're free to look out whenever you happen to need to extend a class like this. So, this extension of the student class is going to include this method. A category is not able to define instance variables, it's only able to define new methods for a class. So, looking at the implementation of this category, again, it's--the category itself is StudentCompare and I am extending student and I'm implementing it basically how I implemented it before, exactly the same, except I'm able to do this without ever touching the original Student.h and Student.m. And this will work exactly the same. Now, in main.m, inside of importing Student.h, I import Student+StudentCompare.h. The StudentCompare.h is what is importing Student.h. And everything else in here is the same. Yes. ^M01:44:42 [ Inaudible Remark ] ^M01:44:51 >> Oh name, OK. ^M01:44:54 [ Inaudible Remark ] ^M01:44:56 >> Oh these angled brackets and quotes. So the angled brackets refer to like these special directories in the file system, in the operating system that it knows to look in to find these files. So like Foundation/Foundation.h is in one such special directory. Whereas these double quotes are what you're going to want to use to refer to files in your current project. So, in this project, I have a Student+StudentCompare.h file. Double quotes is like relative to my current location whereas angled brackets automatically goes to these special directories. Yeah? ^M01:45:36 [ Inaudible Remark ] ^M01:45:56 You mean by addendum, do you mean like this sort of stuff, this category stuff? ^M01:46:01 [Inaudible Remark ] ^M01:46:02 Oh, then yes. So, in student Compare.h, well, let's say Student.h was a foundation class. >> Yeah, yeah. >> Then I would do foundation/Student.h. And inside its main, I would still do the Student+StudentCompare.h. I wouldn't import the original foundation version of things. I would import my version of things that have been overwritten. ^M01:46:23 [ Inaudible Remark ] ^M01:46:31 Yes, it's actually just an extension. It's the--it is the same class. And anywhere else in your code that uses that class could also use that new method. If it doesn't happen to hush import, the correct category file, the compiler will complain that like it doesn't know that method exists. But that method now actually exists for that class. ^M01:47:00 [ Pause ] ^M01:47:02 [ Inaudible Remark ] ^M01:47:03 >> Mm-hmm. >> Where is NSComparisonResult coming from, is that a library? >> So, that's something in Foundation/Foundation.h, we could actually just look it up, NSComparisonResult. So, something about the Apple documentation is that it can be overwhelming. But it has a lot of good examples so feel free to ask questions on like the message board if it--you just find yourself lost in a path of various methods and stuff. So, data types, what was I was looking, NSComparison. So, it looks like NSComparisonResult is--all right, this syntax, you don't even know yet. Let's hold on for that. That's going to be the next thing. But NSComparisonResult is just something that foundation defines. And that's why I wasn't 100 percent sure what it is. I just know that the compare methods of NSString and NSNumber also a different return NSComparisonResults and so that's what I use. But if you wanted, you can construct your own NSComparisonResult to return. OK. Questions for the next thing? So, next thing is this. Again, I think slide is going to be worthless. So blocks, so that's the general format of blocks, but that's worthless so--looking at the example of using a block. ^M01:48:43 [ Pause ] ^M01:48:56 OK. So, back to Student.h and Student.m, I have not modified them to include the compare method. I have not added a category to extend the class. Instead, I've used what's called a block. So a block is kind of like an anonymous function in other languages. It's--it doesn't even have to be anonymous. If you wanted, you could assign it to a variable. It's kind of like, if you're familiar with the term, it's like giving objective-C first class functions to like in objective-C, I'm not really able to just define a function in the middle of this method. That's not entirely valid, whereas, I am able to define a block. So, just like in JavaScript, you saw a syntax like this. Here, we have--we are using a different method. So, before, we use sorted array using selector. Now, we're doing sorted array using comparator. And so, this comparator expects a block that this little caret symbol specifies that what is following this is a block. And this is the return type of the block, NSComparisonResult. This is the two--now this is the type of the first argument and this is the type of second argument. And I know this because if I look at the documentation for sorted array using comparator, its argument is supposed to be a block that returns an NSComparisonResult and takes two arguments that are both IDs. So this, I got directly from the documentation. And then I need to define the function itself so I have my little curly brace. And in here, I'm doing the same sort of thing I did before. We see here that I cast A to student star and that's because in here, A is just an ID, in here, B is just an ID. So if I actually want it to be a student object, I first need to cast it before or passing it a name. So Student star A name, Student star B name, gives me these two names and then I use the NSString's compare method. So I don't have to construct my own NSComparisonResult. And we know that this appropriately returns an NSComparisonResult like this at it should. So blocks anonymous functions. The syntax is a little strange but it's convenient that like I don't need to define a method in the student class just to sort this array, which like that was a very heavy-handed result just to get a sorted array. [Inaudible Remark] Yes. So that's where--I don't remember the syntax. But it's going to look something like--so-- ^M01:51:48 [ Pause ] ^M01:51:51 It's something like what it returns, then in parentheses what I want to call it, then ID, ID equals. And then pass it-- ^M01:52:07 [ Pause ] ^M01:52:10 --to here. Didn't complain. [laughs] So, if you're familiar with function pointers in C, I just sort of used that same syntax. I replaced the star with a caret. So, here is, we are defining a variable called func that is a block as indicated by this caret. This is--the return type of that block is NSComparisonResult. The arguments are two IDs. And you're assigning that to this block. And then we're passing that variable to that function, to that method. ^M01:52:53 [ Pause ] ^M01:52:57 Questions? ^M01:52:59 [ Pause ] ^M01:53:02 OK. ^M01:53:04 [ Pause ] ^M01:53:08 So couple last things. ^M01:53:12 [ Pause ] ^M01:53:19 OK, so protocols. We're not going to go into deep detail today about them. But they are going to be pretty substantial in your iOS usage. So the syntax for this, remember that well, in our interface, we would also say like :NSObject. But here, this angle bracket syntax is how we're going to specify that it must adhere to some protocol. And so the NSCopying Protocol, this is where I'm saying the protocol is kind of interfaces from other languages by saying that the student interface implements the NSCopying Protocol. I'm saying that it must implement the methods that NSCopying says, anything that implements me must implement. So, looking at the implementation now, if we look at NSCopying, it says that you must implement a copy with zone function method. And so here's us implementing it. You don't really have to care about the syntax of it for now or the--what it actually is doing. Just the idea that since student implements the NSCopying Protocol, it must implement all the function, all the methods that NSCopying says. And the use of this as we see is going to be like a lot of these functions that--or a lot of like classes that you're going to be using with iOS, like a lot of these drawing classes, are going to expect you to pass it objects that must adhere to certain protocols. For example, UITableView is one. Let's actually looked at documentation, this documentation work. ^M01:55:02 [ Pause ] ^M01:55:12 OK. So we see in the documentation that it looks like a data source. So, UITableView is, in like your iPhone, it would be like your contact list sort of, it's just like a bunch of rows with data in them and you can scroll up and down on it. So here, UITableView defines a data source property where the type of that data source is just an ID that implements UITableView data source. And so this is important because if you then set this property to be some object, that means that that object must implement this protocol, what this protocol says must be implemented are--so some methods are optional, some are required, so these two methods are required. And so, when you set that property of a UITableView with some object, that object must have these two methods. Let's say, like how many rows there should be in this table, in this section, and also what should go in each particular cell. So when you try to create a TableView, you need to pass some object that is capable of populating the cells of that TableView. And so, UITableView knows that you are capable of doing that if you implement the protocol. And you'll see that that sort of pattern is going to be pretty common with a lot of things you do. Questions with protocols? ^M01:56:51 [ Pause ] ^M01:56:55 And that's really why I like it. You compare to like a Java interface. Protocols are much more similar to those since like protocols almost define a new type kind of, whereas like an interface in Objective-C is just a list of all the methods that you implement. It doesn't say anything intelligent about like, "OK, you're welcome." Really, what protocols allow are like multiple objects to all--multiple classes to all fulfill some common purpose. So as long as like--an example are all these like enumeration classes, the collection classes, NSArray, and NSDictionary, and all those, as long as you appropriately implement some protocol, then you are able to use the fast enumeration syntax on that object, that for...in syntax. And, again, much more than that. All right. Just--so you've seen it. NSExceptions is very similar to some other languages, the try and catch blocks and we also happen to have finally. So that's just to know it exists. You probably won't even use them that much, but that's useful to know. NSError is somewhat of an alternative. So, instead of having to use like the try-catch-finally syntax can be somewhat large, especially if like each one of those do something here, just like a single line then you've sort of like wrapped it with three times as many lines are accomplishing something. So, NS--or well, this sort of syntax, this is one of the rare scenarios where are you are going to be using ampersand still, so--again, we're never dereferencing an object, but we are passing the address of an object. We are passing the address of this NSError so that if something happens to go wrong when we pass the method bar--the method is called bar:error:. So when we pass the method bar:error: foo, if something happens to go wrong, then foo will instantiate an NSError object and set E to be that NSError object. So, inside of here, if something went wrong, E will not be nil. If we just pass E, then inside of this function, this method, it would have to dereference E which is something you shouldn't be doing. You should never dereference an object. Plus, if you try to dereference E, you'd be dereferencing nil. ^M01:59:40 [ Inaudible Remark ] ^M01:59:46 So it will--by returning nil, it's indicating that something went wrong and then inside of here, now, since something must have gone wrong, E must be set to something that isn't nil. Inside of the function, it must have instantiated an NSError object and did like star--star E equals this NSError object. ^M02:00:08 [ Inaudible Remark ] ^M02:00:19 Well, it's--well, the function or the method is bar error, bar:error:. But if something goes wrong, yeah. It--that's just like when you read the documentation, it will say like, "If something goes wrong, nil will be returned and error will be set to some NSError." So, it's also possible that it will return void and then it's up to you just to see if E is still nil and that's the way you know there was an error. But, that's just--in this example, we say, nil is returned on error and what that error was is inside of E. [Inaudible Remark] Yeah, it's not. So, instead of just failing, we just put it inside of E. But other things do use the try-catch syntax so some things don't have this. All right. Any other questions? ^M02:01:14 [ Pause ] ^M02:01:17 I think that's it for our Objective-C intro. If there is anything left, it was a lot, but we haven't really done any iOS stuff so we'll throw all that at you next week.