Tip:
Highlight text to annotate it
X
[ Music ]
>> Stanford University.
>> Alright, so welcome to Stanford CS193p,
fall of 2013-14 academic year.
This is our very first lecture and we are going
to be covering developing applications
for iOS, so specifically iOS7.
Today's lecture kind of has a first part and a second part.
The first part is a little bit of logistics.
The second part is I'm going to dive right
into the course material because there's a lot to cover and so,
we need to start covering it.
[Pause] So, what will I learn in this course?
I think you know what you're going to learn in this course.
You're going to learn how to build cool apps, okay?
iOS is a really cool platform for building apps,
you probably already know that.
The apps look cool, they've got animation.
What's really cool is they're in your pockets
so you can whip them out and show them to your friends.
You don't have to send them to a website or go get a computer.
It's also really easy to develop really powerful apps
in a really short amount of time, as you're going to find.
This course is only 10 weeks long,
and while this is Stanford, I know, you're all really,
really good programmers and all that, it still,
10 weeks is not a lot of time, so when we get to the end,
you're going to see that it's a very leveraged platform
for building things.
And, you know, the community is quite vibrant,
being able to distribute your apps via the app store
and not have to put them in a box and put them on a shelf
in a store, is really a big, big difference when it comes
to marketing a product.
Okay? And you'll, you'll see that.
The second thing you're going to learn
in this course though is real-world application,
a lot of the computer science things you're learning
in other classes.
Okay? So, we're going to be doing networking,
we're going to do multithreaded,
we're going to be doing all kinds of graphics,
we're going to be doing animation,
we're going to do object-oriented databases,
we're going to do all that stuff for real, okay?
You're going to see what it looks
like to apply all those computer science concepts, especially how
to combine them into a real-world platform,
where you're making real apps, okay?
And quite a few, many dozens
of my former students have shipped their apps
on the app store and you may well too.
Okay? So this is really, this is a good course to kind of combine
or synthesize all of the things you've learned in a lot
of your other computer science classes and touch it
up against the real world.
Okay? The prerequisites for this class are super duper important,
okay?
This, it's just key to make sure you have these prerequisites
and really think long and hard, if you don't, whether you want
to give this class ago.
CS 106 A&B or, or CS16x are absolutely required, okay?
If you don't have that or equivalent, definitely,
don't even think about it.
The second requirement I've added this quarter,
based on experience, is CS107 or CS108, which is great,
by the way, if you're taking CS108,
you'll really be ready for this class.
Or even CS110, and part
of the reason I'm requiring these extra classes is just
so you're farther along the programming experience curve
because this class is a lot of programming, and so for those
of you who are used to a lot of programming,
you, you're used to it.
But for those of you who aren't it's kind of like, whoa,
do a lot of programming here.
It's going to be a little unbalancing.
So, that's why I've required all those.
Now if you've done a summer internship
of you've done some programming or something like that,
that's definitely a substitute for CS107, 108, or 110, right?
Or if you've done some other CS class that's even more advanced
than these, that's fine too.
You've just got to understand that this class is, you know,
a programming class, there's a lot of programming.
And most importantly, you got to really be comfortable
with object-oriented programming.
So I put a bunch of terms up here, like message
and instance variable and superclass and subclass,
if you don't know these terms like the back of your hand,
it's going to be hard for you to get this class,
because I'm going to be throwing those terms
out left, right, and center.
iOS7 is completely object-oriented.
Okay, the whole structure,
the design of the thing, is object-oriented.
So, you just got to know that, and if you don't know that,
you definitely want to go get that first.
Okay? Take CS106a&b equivalent first,
and then get a little more programming experience
and then you're good to go.
Okay? We're going, you're going to be writing apps in this class
with dozens of classes that you're going to write
by the fifth, sixth week so, you know,
if the biggest app you've ever written is got 3, or 4,
or 5 classes in it, oh, this is going to be a step up.
Okay? The assignments, we've got this weekly assignments
for the first six or seven weeks,
and then you've got a final project at the end.
All of the homework assignments have detailed write-up
of the required task and what we're evaluating you on.
And they also have hints in there, because I'm not trying
to make the homework assignments be really, really hard,
and all the homework assignments also directly are re [pause],
they're basically reinforcing what has been taught in lecture
in that week, they're not a bunch
of random new stuff to learn.
I'm a big believer in a teaching methodology, which is I'm going
to tell you about a concept, via slides, and then I'm going
to show you it by demoing it to you,
actually writing an application that does, then I'm going
to ask you to do it on the homework.
So that's three times you're going
to see every single thing pretty much in this class.
By the end of that, you're going to know how to do it.
Okay? And you're going to feel confident
and experienced to do it.
So the homework is all about that.
It's about just doing what you saw me do in class and talk
about in class and apply it.
Alright. Now I'm going to really briefly go over what's in iOS,
I think most of you know what's in iOS,
hopefully you've all seen an iOS device or you have one
in your pocket, I bet 90 percent of you do in this room,
but I'm going to try and summarize it,
this is really hard to do because I'm going to try
and do it in four minutes or less, or five minutes,
and it's so big that, I mean, I could have two lectures
where I just talk about all the different things
and just summarize them.
So, this is going to try and group them into some sort
of sensible groups so you have an idea of what's there
from a development standpoint, then when we go off
and start doing it all then you'll start realizing whoa,
and once you learn how to look in the documentation you'll see,
oh, look at all that stuff in there, and you'll figure it out.
So this is just a high-level overview.
So, I, I've used this division into these four, kind of groups.
Core OS, which is the stuff that's close to the hardware.
Core services, which is an object-oriented on top of that,
that kind of makes it
so you always are programming an object-oriented layer.
Media, because these devices are basically iPods with a phone
in them or with a big screen on them,
but media is really important to these devices,
and then finally Cocoa Touch, which is the UI layer.
Okay? Of buttons and all the switches, things like that.
So let's talk about what's in each of those layers, kind of,
little skimming the surface of what's in those layers.
At the Core OS layer, near the hardware, is a Unix kernel.
Okay? This is a Unix operating system on this device.
And BFD-based mock, and so you get everything you get
with Unix.
You're getting sockets and you're getting file system,
permissions, all that stuff, plus you're getting a bunch
of other stuff that's kind of specific to a mobile device
like this, like power management, and key chain access
to kind of manage the security of things.
Bonjour, which is this kind of network,
finding other things on the network.
So it's got all that stuff,
it's a very powerful underlying operating system.
But all of that API or most of it is in C,
and we want to be programming kind
of purely object-oriented layer.
So we're going to be mostly operating when we're talking,
touching those things at the Core surfaces layer.
So this layer has things like language, things that,
that kind of make the language more powerful, like arrays
and dictionaries, and strings and things like that,
plus it has object-oriented ways to access the file system,
it has object-oriented ways to find out the GPS location
of your device, for example.
It has ways to do multithreading.
All this stuff what you want to be able to do, but you want
to stay in an object-oriented kind of mindset
as you're doing them all.
There's a huge layer, foundational layer there
at Core services for doing that.
At the media layer, don't sleep on this layer,
really important layer, you've got video here,
you've got video editing, you got images, of course,
that it can display, it's incredibly powerful audio
for doing 3D audio, if you have games,
you can make the Thai fighters feel
like they're ripping by you and stuff.
All that stuff is in here.
This is part of, the part of iOS
that really I can't cover in a lot of depth.
I'm just going to try and let you know that it's there
and you're going to dive down depending on what kind
of applications, later in your life, you want to build.
But there's an enormous amount there.
This is a fundamentally, a multimedia device, obviously,
and then, Cocoa Touch is where we're going
to spend most of our time.
This is where you are going to be building buttons and sliders
and text fields, talking to each other, and animation happening,
things sliding in and out, and, you know,
fading out and fading in.
If you want to get the, a picture from the camera
from the user, you can do that.
Things like localization so that you're app can run
in many countries in the world and up your sales by doing that.
A whole map kit for doing all the 3D maps
that you've probably seen in iOS7 and all
that stuff is all in there.
And, there's even a view
in there that's an entire web browser in a little rectangle
that you can just plop right into your app.
So these are really high-level objects, and we're going
to really be diving into this layer, alright?
So this is really the primary.
And it's called Cocoa Touch because the API
in here was originally developed for Mac OS X,
and it was called Cocoa, and of course then when they went
to iOS, they adapted, and a lot of API is shared
between the two platforms, and, in fact,
if you develop an iOS app and then you say someday, oh,
I want to develop an app for the Mac using Cocoa,
it's going to be very similar.
Okay? You're going to be really, it's going to look familiar.
So Cocoa Touch, obviously,
is the touchscreen version of that, of Cocoa.
Okay?
This technology, Cocoa, has been around a long time, okay?
Probably almost 30 years, believe it or not.
From even before Apple acquired it to make Mac OS,
what is now Mac OS X, and so it's a very mature API, okay?
And it's very well thought out, so, especially if you go
with the flow of it, it's very easy
to build really powerful things.
So, that's what's in there.
So let's talk about the tools we use as programmers,
as developers, to build these apps, okay?
And I've divided those into kind of four sections here.
One is the tools, the actual programming tools,
and what's great, on this platform,
is itÕs pretty much a one-tool fits all.
Okay? There's this one tool, XCode 5,
and everything's in there.
You're debugger's in there, all your source code editing,
your source code control, the UI building,
everything is in this one app.
There's a little adjunct there, instruments, which is for things
like profiling your app and things like that.
Memory usage, those kind of things, but you're really,
all was inside XCode 5, which is really nice because, you know,
when you're debugging, you're usually editing your code
at the same time, back and forth, back and forth,
you're going to different apps and all that would be a pain
in the neck, and they've really done a good job
of arranging the screen space so that it's sharing
between all these different tasks that you need to do.
So that's the primary tool, XCode 5, you should all,
right after this class if you want, go to the Mac App store,
not the store on you iOS device, the Mac App Store
on your Mac, and download this.
It's free, available, came out last Friday,
and you can download it, install it, and, you know,
start playing around with it.
Some of you might have already used XCode, like in CS106,
raise your hand if you've used XCode before for anything.
Okay, so two-thirds or more, three-quarters of you.
So, you're going to be used it.
You're just going to start using XCode now
to develop for iOS, alright?
There's a new language for you to learn, objective C,
it's kind of a funny-looking language, okay,
its square brackets and colons, no parentheses on message calls,
which is kind of weird for people who are coming
from Java or C++ or whatever.
The arguments are not put in parentheses or whatever,
and I'm going to show you all about objective C,
I don't expect you to know anything about it coming in,
and if you know Java and C++, which you should
if you've taken CS106A&B, then objective C is not going
to be a big leap for you.
It's a little bit different language,
it's a little more fast and loose than Java, for example,
and it's a little more, kind of simple and elegant, than C++,
when it comes to the object-oriented stuff.
So, I think you'll like it.
It won't. Some of you who are very, you know,
correct programming kind of thing, you love Java,
might find objective C a little wild west for you,
but you'll get over it.
Frameworks, obviously, any big system like this groups all
of its objects into libraries, essentially.
We call them Frameworks in iOS,
so there are dozens of frameworks in iOS.
The two main ones we're going to look at, at the beginning
of the course, are foundation, that's where all
that core services stuff is, like arrays
and dictionaries and all that.
And then UI kit, okay, that's where buttons and sliders
and all those things area, so those are the two main ones,
but, there's a whole bunch of other ones, like,
you see the Core Data written up there,
that's the object-oriented database.
Okay? So we're going to be doing that.
Core Motion, that's the gyro and accelerometer.
Map Kit, obviously the maps.
And there's dozens more, okay?
And we'll cover as many of them as we can,
obviously we can't do it all in 10 weeks,
but we'll do as much as we can.
And then the last part of developing application
in this platform is a design strategy called MVC.
Now, this is not unique to iOS, other platforms use MVC,
Model View Controller, as their fundamental design strategy.
So how many people in this room have used MVC on any platform?
Okay, so about half, so you'll know what this is.
So, I'm actually going to go over MVC for those of you
who haven't and I'll go through it pretty quickly,
because it looks like most of you, half of you have done it,
and [pause] the main thing to see in MVC here,
for those of you who already know what it is,
is to see how I talk about it so that when we get into iOS
and I start saying things like your model is UI independent,
you'll know what I'm talking about
and we'll all be on the same page.
So this is mostly kind of getting us all
on the same page terminology-wise.
So MVC, Model View Controller, is essentially a strategy
for how to organize all the classes in your application.
And what we do fundamentally is we divide all the classes
into one of three camps.
The model camp, the controller camp, or the view camp,
and what, how you decide what goes in each of these camps,
well, the model is essentially the what of your program.
What is your program?
So, as we're doing this MVC talk, I'm going to talk
about our first application we're going to build
which is a card matching game.
Okay? So we're going to build this game, it's gotta bunch
of cards on the screen, like playing cards, you know,
Ace of Clubs and all that, and you're going to be able
to go choose the cards
and you'll get certain points if the match.
Like the suit matches or the rank matches, or whatever,
you get more points, less points whatever, but you're doing that.
In that kind of application, a little card matching game,
the cards and the deck, and even the logic
for how the game is played are all UI independent
and in the model.
Okay?
So how the cards get drawn
on screen is the job of the controller.
So the controller is, it's job to figure out how am I going,
you know, take this set of cards and display them on screen,
and then animate their movement and things like that.
Okay? That's up to the controller.
So the controller controls how the model is presented
on screen, and the view, the minions,
the classes that the controller is going to use,
kind of like the building blocks, the Lincoln Logs,
I don't know maybe that's before all your time, but, you know,
the things we're going to do build our UI we're going to use
in the view, so, the stuff that's
in the view is pretty generic.
Generic UI elements, the stuff
in the controller is very specific to how your UI works,
and the stuff in the model is completely independent
of how you're UI works.
Okay? So, doing MVC is about knowing where things go,
but also about how to communicate
between these three camps and so I'm going to try
and summarize how the communication works
between these camps and I've used road markings,
you see the double yellow line and then the dashed white line,
so that's like you're driving in your car, try to use them
as that I have an image for how this communication happens,
where it's allowed, where it's not allowed.
Okay? So let's talk about the controller talking to the model.
Okay? Going from that side of the road
over to the model side is a dashed white line,
in other words, you can head right across there,
you probably want to look before you go,
but you can go right across, okay?
The controller has to know everything about the model
and it has to have complete ability to talk to the model,
use its public API as much as it wants,
because the controller's job is to present the model
to the user using its view as its minions,
so it has to have this access.
So that's full, unrestricted access the controller has
talking to the model.
This is a one-way era, or one-way arrow,
from the controller to the model.
And similarly from the controller to the view,
is also unlimited communication
because the controller is responsible for talking, using,
it's own minions, the view is the controllers' minions to lay
out the user interface and all that stuff,
so the controller can do anything it wants,
I've put that little green word outlet up there
because when we have a property of a controller that points
into the view, we call it an outlet.
Okay? And you're going to see that in the demo on Wednesday,
I'm going to say oh, let's create an outlet
from our controller to our view
so our controller can talk to its view.
Alright? What about this communication?
Model to view, never, and why is that?
100 percent obvious.
The model is completely UI independent.
So there's absolutely no way it could talk to a view or object
or anyone in that camp.
Because the view objects are fundamentally UI objects,
they're kind of generic,
but they're still fundamentally UI objects.
Similarly, since the view objects are kind of generic,
they can't be talking to any specific model.
They need a controller to interpret a model for them.
Okay? So there's never any communication this way,
that's why it's a double yellow line,
that's why these lines are red, that's why there's fire, okay?
Never go across that line, ever.
[Pause] What about the view talking back to the controller?
You got these generic view objects, like buttons,
can they talk to the controller?
Well...yes, they can, but they have to be careful
because the view objects are generic,
so they can't really know much about the control, so,
they can only communicate back to the controller
in a blind way, where they don't know the class
of the thing they're talking to, and, in a structured way,
a way where we all agree, we're going to communicate this way,
between the view and the controller,
so what's an example of a structured way?
Well one is called target action.
So the controller basically drops a target on itself
and then it hands out an action, which is like an arrow,
to the view and says to the view, okay,
when you do what you do, like you're a button
and someone touches you or you're a slider
and someone moves you, send me that action.
Okay? So in this way, the generic button, or slider,
is communicating back to the controller, it has no idea
that it's a card game controller or a space game controller,
it doesn't know what kind of controller it is,
all it knows is that when something happens in itself,
boom, it sends messages to targets.
So that's a blind, simple, structured way for the view
to communicate with the controller, okay?
But what about more complicated ways?
Sometimes the view, things are happening in the view
that are somewhat complicated and the controller needs
to be informed of what's going on,
synchronizing what's happening.
And one way to think about this is these words I put here, will,
should, and did, when the view is kind of like [pause],
let's say on the scroll view and I'm scrolling around,
and I want to let the, the controller, somebody,
know that the user just did scroll.
Okay?
Or the user puts down the touch and is about to scroll,
I want to let the controller know the user will be scrolling.
Okay? Or the user puts a touch down and the scroll view wants
to know, should I allow the user to scroll here, is that allowed?
All those things, the scroll view itself might not have
enough logic to know the answer to those questions,
so what it does is it delegates the authority
to answer those questions to some other object.
Now it doesn't know the class of that object, all it knows is
that other object can answer these questions, will, should,
did, this, that or the other thing, like,
should allow scrolling,
did scroll to point, things like that.
So those are the kind of methods you're going to see
in these delegate protocols.
Now I know that CS106A&B do not teach protocols, the word proto,
how many people know what the word protocol means
in object-oriented programming?
See, very few of you, so I will be teaching that.
A protocol is just a blind way to talk to another object.
You're, you're going, when I teach you, you're going
to be like, oh yeah, I know what that is,
we didn't really call it protocol, or whatever.
But, that's how we do delegation, okay,
this blind communication.
Also, another important thing is
that views should not own the data that they're displaying.
They should not own it.
In other words, it shouldn't be a property inside of them
where that's the truth of that data.
And the easiest example for this is all the songs in your iPhone,
on your phone or your iPad, right?
You might have 10,000 songs in there.
So if you have some kind of generic list view in your view,
you can't transfer all 10,000 songs to its instance variables
and expect it to hold 10,000 songs so it can list through it.
A, that would be inefficient, and B, that information,
those 10,000 songs belongs where?
In the model, okay?
Because you're song database is a model.
It has nothing to do with UI's, just a list of songs and artists
and albums and all that, it's in the model.
Some controller has to look at that database
and tell a view how to display all those songs, okay?
So, we need that communication to happen here
and the view is displaying some sort of list,
and you're touching down and you're flicking on the list
and trying to see more songs,
how does that communication happen, and the answer is,
we have another special kind of delegate,
which we call a data source.
Now the data source doesn't do the will, did, should,
it's going to be asking questions like count,
like how many songs are there?
And the controller looks in the model, 10,000.
Response to the view, there's 10,000.
The view makes space, internally, for 10,000 things,
it doesn't know what they are,
moves the scroll bar indicator a little bit, so that you know
where it is, and then you start scrolling, flipping through it,
and its start sending the message to the controller,
give me the data at [pause] line 150, next 10 items.
See what I mean?
And then you flick down some more, now it's saying 250,
10 more items, and so the controller is going back
to the model and saying give me more, give me more data,
and it's providing it to the view in this blind way.
So see how the view is getting data from the model
through the controller, in this kind of blind structured way.
Okay? That makes sense to everybody?
So data source is just a kind of delegate, it's a specific kind
of delegate for getting data.
So you're going to see that there are classes in iOS
that have a data source,
and they usually also have a delegate.
Most sophisticated classes in iOS have a delegate, the will,
did, should kind of things.
Some of them have a data source,
it depends on whether they're showing a lot of data or not.
Now simple data, like if I had a view, if I invented a view
for my card game called playing card view,
and it just has a suit and a rank, okay, we're not going
to do count data at for just suit and rank, we are going
to set those properties.
And so the view then would have those, that data set in it,
but it wouldn't be owning it, right?
The model would still be owning the suit and rank,
the view is just getting that data to present it.
Okay? So simple data we might transfer to the view,
but it's merely for it to display it.
Okay. This all adds up to the controller's job being
to interpret and format the model data for the view.
That's the controller's job.
And when we do our demo, I'm going to be marking like, oh,
see, I'm writing this code,
this makes the controller perform its job,
which is to take the model data and put it in, and using it
to view minions, put it on screen, okay?
That's what the controller does.
What about this communication?
Can the model talk to the controller?
Again, obviously that's verboten because model knows nothing
about UI, so it couldn't possibly talk
to a UI object like the controller.
But sometimes things change in the model
and the controller needs to know about it.
Okay, data changes, a database changes
or the model is some network database
and somebody changes something on the network and it changes,
and the controller needs to find out.
So, how do we do that communication?
We do that using kind of a radio station model.
Okay? So the model, a radio station concept,
the model will use this concept
to essentially broadcast information
to anyone who's interested, okay?
And the mechanisms for doing this
in iOS are called notification and key value observing,
KVO we call it, and so the model can just say, oh,
anytime something changes in my model, I'm just going
to broadcast on my radio station
and then the controller simply tunes into that radio station.
And it can find out things are changing.
And when it finds out something changes,
it's going to communicate via its green arrow to the model,
and say, okay, give me that data that changed.
Alright? Does that make sense?
So towards the end of the quarter,
we'll start seeing a little how to do notification to find out,
for example, if the data in the database changes.
We'll get a notification, the UI can then, you know,
the controller can then go talk to the model to get the info.
Okay? [Pause] Some people have asked, can a view tune
into the radio station?
They probably could, but you probably wouldn't want
to do that.
That would probably be a violation of MVC.
Alright, so, we do this, we have all this nice communication
and all these rules, and we can imagine building something
simple using this, but what if we want
to build a big, complicated app?
An app that has multiple screens on our iPhone
or on an iPad it's got, you know,
three or four different areas on screen
where things are happening, how do we do that?
Well, we're essentially going to combine multiple MVC's, okay?
Because you, an MVC can use, as part of its view, another MVC.
Okay? So, an MVC, an entire MVC,
can be one of the minions of some bigger MVC.
Okay? And by doing that and cascading it down,
we can build more and more complicated applications.
So, an example of this is you might have your calendar app,
and it's showing you the entire year, and you click on a month,
and now it shows you a month view.
Well a month view looks a lot different than a year view.
Month view just has all the days and maybe some circle
that tells you where you have an appointment on a day,
and then when you click on a day, and now you get a day view.
Okay? And the day is showing you the hours
and what all your appointments are, and you click
on an appointment, and now you get an appointment view
and it's showing the detail of where you're going
and when it is etc. Okay?
Well each of those views, the year view, the month view,
the day view, and the appointment view are their
own MVC's.
Okay? But you can see how the last three, okay, are used as,
essentially, a minion of the top-level view,
the year view, to show more detail.
Okay? So the year view, you click on a month,
it's going to use the month view MVC to show more detail,
so it's part of its view, okay?
So, you see this also in iOS with tab bar controllers, right?
You have the tab bar, along the bottom, I have four
or five things you can choose, well there's some MVC at the top
who has four pointers to four minions,
which are the four MVC's that are each going
to appear in a tab bar, okay?
We'll be doing that, for example,
in assignment number two or three,
where we'll be making a tab bar and you're going
to have to do multiple MVC's.
Okay? So, that basically results in a picture
that looks kind of like this.
Alright? Where you got this MVC
and you see the purple one that's
like underneath the word together there, and it points
to three other MVC's outside of its view thing, okay?
That's how we're going to build this,
that might be a tab bar controller
and those might be the three tabs.
Okay, and each one is its own little MVC,
completely independent, operates on its own,
doesn't even know it's a generic, reusable view
like thing at this point, it doesn't even know
that it's in a tab bar.
Okay? It just knows that it's supposed to do whatever it does.
And so it's modular in that way.
You can also see that there's no communication between any other,
there's no other arrows, except for some of the models.
You see some of the models are communicating with each other,
you know, a big application might have single, shared model.
Or, you know, the models might be split off into pieces
to be used by sub MVC's, okay?
But that's the only kind of communication you're going
to have there, all other communication is either the
structured communication we saw in the MVC or it's using MVC's
as part of the view of another MVC.
Any question about that?
So we definitely don't want to be having designs
that look like this, okay?
Where everybody's talking to everybody,
we can't tell who's talking to what, it's just impossible
to debug a program like this and it doesn't scale.
You can't build really big programs this way,
it just becomes impossible
to know how touching anything would break everything, right?
So we're definitely not going to be doing that.
Okay? Okay, so that's MVC.
No questions about that?
Alright. Onto objective-C.
So, objective C is a strict superset of C,
so everything you can do and see, you can do in objective-C.
Okay? And we'll do a lot of C things in this class.
We'll do a lot of object-oriented stuff too,
but we're going to do a lot of C things, as well.
But, there's obviously a few things that you want
to think differently
about because you have object-oriented stuff added
onto a language, and we're going to talk about one of them today,
in addition to showing you a little bit of the syntax,
we're going to talk about one of these different,
think differently things about objective-C that's different
than C++ or Java, which is properties.
Okay? And I'm not going to read through all of this,
I'm just going to show it to you,
but properties are basically how we access our instance variable,
right?
Everybody knows what I mean by, raise your hand
if you know what I mean by instance variable?
Okay good.
So pretty much everybody.
So, we want to access the instance data of our objects.
And, normally, in Java or in C++, you just, you know,
have some syntax to access them and you just access them.
In objective-C we don't do that.
In objective-C, we have what's called a property,
and a property is basically a setter get method
and a getter method.
And that's how all access to the instance variable goes,
through a setter method to set the value
and a getter method to get it.
And some people who maybe are kind
of [pause] performance junkies might say, oh my gosh,
every instance variable I have
to call a method to set it or get it?
But, remember, you're building
for a user interface system here,
when the user touches down, that's taking million,
a million code, you know,
you're executing a million instructions there
in that amount of time.
So, having a few extra setters
and getters is completely irrelevant, right?
So it's the old [inaudible] thing, right?
You don't want to optimize things that don't need
to be optimized, okay?
You want to optimize the things that are taking a lot of time
and accessing instance variable turns out not to be taking a lot
of your time, so, let's look at what it looks like,
don't get freaked out here by seeing this syntax.
It's all new, so, it's going to take some getting used to.
In objective-C, every class we have and the class I'm going
to show you today is a, is in our, essentially our model
that we're going to build for our card game matching app.
We're going to have a card and a deck, and we're also going
to have a subclass of card called playing card
and a subclass of deck called playing card deck.
Those are the four classes that are going to be
in our model, to start.
And, so, I'm going to show you,
in today's lecture I'm just going to show you card,
only card, and then on Wednesday I'll show you deck
and playing card deck and playing card.
So, every class in objective-C, you have a header file, card.h,
and you have an implementation file, card.m. Okay, this is just
like in C++ you might have that h and dot c, or whatever,
this is dot m, m I guess is for implementation, I don't know.
But it's m [laughter], and so you have these separate things,
the difference here is card.h is the public API.
That's what your dot h is.
It's your public API.
Card.m is your private API and all your implementation, okay?
Don't get confused about dot h
and dot m. All dot h is your public API, that's all it is.
It's what methods in your class you want to make public
so that other people can call them, okay?
So, let's see what the syntax looks like.
In your public API, you must say who your superclass is.
Okay? You are not allowed
to make your superclass be a secret, okay?
It has to be public so we have to put it in the header file,
and you can see the syntax we use is at sign interface,
the name of our class, which should always match the name
of the file, by the way,
card.h should always have the interface for the class card.
And then a colon and then your superclass.
Now the superclass of the card class is NSObject.
NSObject is in the foundation framework
and it's pretty much the root class of every single class
in all of iOS, including all the classes you write.
Okay? It's this kind of basic class, we'll talk about it
when we talk about foundation, but it's going
to be the superclass eventually of every single class.
Right? Everything, eventually, inherits from NSObject.
Now, on the implementation side, it looks very similar,
but instead of saying at sign interface,
you say at sign implementation and the name of the class.
And here you don't specify your superclass, okay?
Because you're only allowed to specify that once,
and its public, so it goes in your header file.
Notice that the bottom of both of these,
little at sign end, do you see that?
Okay, that just means that's the end of the interface
or of the implantation.
Okay? So all of your public API goes inside this
at sign interface block, at sign interface,
and all of your implementation, your private implementation goes
in the at sign implementation part.
Now, if you import, if you have specified your superclass here,
you have to import it.
Okay? Which is like pound sign, include.
It's a little more powerful than pound sign, include, in fact,
it's a lot more powerful, as I'll talk
about in a second here.
>> But you must import it,
otherwise the objective-C compiler won't know what
that superclass is, so you have to, obviously,
import your superclass.
However, we don't usually,
when our superclass is something that's in iOS,
we don't usually import just that classes header file,
which in this case is foundation,
we actually import the entire framework.
Okay? Now you might say, oh, that's inefficient.
[Pause] A huge framework,
but of course this is all precompiled and optimized.
And, in fact, in iOS7, the syntax for this is really to say
at sign import foundation.
That means I'm going to use all the public classes
in the foundation framework.
iOS7 still supports the old important foundation slash
foundation.h so you can use that if you want.
Now on our implementation file,
we have to import our header file, obviously.
Okay? Because our implementation file needs
to know what we're committing to publicly, in terms of our API,
so we have to import that.
Makes perfect sense.
We can also have private declarations, okay?
Declarations of properties and methods that are private inside
of our implementation file by putting this little
at sign interface, name of our class,
open parentheses, closed parentheses.
Okay? And then at sign end.
So we can have a little space here
where we can little private declarations.
Now, objective-C does not require you
to declare something before you use it in a file,
you know what I mean by that?
And there's a lot, a lot of languages,
you have to declare a method before you can call it, right?
But you can do it out of order in objective-C,
you can implement a method here that calls,
you can implement method A, calls method B,
and then method B is implemented down here later in the file.
Okay? So you don't have to declare method B first,
then implement method A, and then implement method B. So,
this little private at sign interface we're mostly going
to use for properties.
Okay? Because when we declare a property, as you'll see,
that setter and getter get written for us.
So let's see what that looks like to declare a property.
So here's a simple property.
It's called contents.
So this is the content of the card.
This is what's on the card.
So this might be ace of clubs.
Okay? And because this is your first day,
we're going to make the contents be very simple, just a string.
Okay? So these cards, they can be like a flashcard, maybe,
for learning a foreign language, maybe this is the,
the contents are the word that you're trying to learn
and maybe it's a flashcard of images
where this content is the name of some image and it's up to UI
to display an image that matches it.
Or in the case of our playing cards,
we're going to have this be like, literally the character A
and then the character clubs,
because there's Unicode character clubs, so the A clubs,
that would be the content.
So this is the content of the card, what's on the card.
And you can see that it's an NSString star.
You see at sign property is how we're going to declare
that we need storage, per instance of card,
in other words every card has its own contents, and it's going
to be a string, and so we say property NSString star, now,
it's important to understand that in objective-C all objects,
all of them, live in the heap and we have pointers to them.
Okay? There's no such thing as making an object on the stack
or anything like that, okay?
They're all in the heap.
Everyone knows what the heap is?
Any questions about that?
That's just where you allocate free memory.
So all objects are there.
What's' really cool about objective-C is,
objective-C will manage all that storage for you.
It will allocate for you and free it for you.
Okay? Now how does it know when to free it?
And the answer is this strong thing,
you see the word strong there?
If, your properties can either be strong, like this one,
or weak, two things, strong or weak.
Okay? And all pointer properties have to be strong or weak
because the objective-C has to know what to do
with the memory and the heap.
Strong means keep the memory for this,
for the thing this points to, in the heap, as long as I
or anyone else has a strong pointer to it.
Okay? So, this is called reference counting,
it's not garbage collection, its reference counting.
So we're going to, the objective-C is going
to keep track of every single strong pointer to an object
in the heap and as long as at least one strong pointer exists,
it's going to keep that thing in heap.
As soon as there are no strong pointers left,
it will free the memory out of the heap, instantly.
Not garbage collected later.
But actually instantly, reclaim that memory.
Okay? So this is probably new to you, you're probably used
to like garbage collection in Java, for example,
or explicit memory management in other languages.
This is called automatic reference counting
and it's awesome.
It's really very predictable, this is much better
than garbage collection, because, you know,
the garbage collector can come along later and do,
wreak havoc on the performance of your application as it goes
and collects things from the heap.
This is very predictable, you know exactly
when things are going to be released,
it's when there's no strong pointers left to it.
What would it mean if this was weak?
Okay, if you have a weak pointer, that tells objective-C,
okay, I have a pointer to this thing in the heap and keep it
in memory as long as someone else has a strong pointer to it.
But as soon as no one else has a strong pointer to that thing,
it gets freed from memory and this pointer,
if it was weak, gets set to nil.
Nil means this pointer doesn't point to anything, okay?
Nil is the same as zero.
Okay? In other languages, you're probably afraid of nil pointers.
Okay? Because you do reference a nil pointer,
it crashes your program, right?
In objective-C, you can send messages to nil pointers even
and it will not crash your program.
In fact, if you send a message to a nil program,
to a nil pointer, it will not execute any code, obviously,
because there's no instance there.
And it will return zero from,
if that message had a return value, it'll return zero.
So you have to be a little careful of messages
that return structs, okay,
but as long as it returns a primitive type or a pointer,
it'll just return zero.
So, this is going to take getting used to.
The fact that we are going to program knowing
that we can send messages to nil,
to pointers that are nil and that that's good.
We'll actually make our code work nicely and we'll use
that to our advantage.
And that is definitely going to be a change for you who are used
to if pointers not nil,
then send message all the time, right?
Protecting against crashes, you don't do that in objective-C,
you just don't code it that way.
Okay? So, this pointer could have the value nil, n-i-l,
which means it doesn't point to anything.
Alright? So if you have a strong pointer and it points
to something and then you set it to nil,
now that strong pointer doesn't point to that thing,
as long as no one else points to it, you can clean
up that memory, objective-C will clean the memory up for you.
Or if you have a pointer that points to something in the heap,
then you make it point to something else in the heap,
then you no longer have a strong pointer to that other thing
in the heap and as long as no one does, it'll get cleaned up.
Okay? And remember weak not only cleans it up,
but it sets your pointer to nil,
because you only wanted a weak pointer, you only wanted it
to point to that thing as long as someone else does.
Okay? So that's the strong versus weak.
The other thing we're going to put
in this little parentheses is nonatomic, okay?
Nonatomic means calling this setter and getter that go along
with this property is not thread safe.
Okay, so you can't have two threads trying
to set this property at the same time.
Why do we say nonatomic here, why do we want this
to not be thread safe?
Because the way we do multithreading in iOS is not
by having a single object that multiple threads are setting on,
we usually have a separate set of objects that are running
in another thread, like your model, and then other,
than your UI stuff is running in the UI thread
and they're talking thread to thread.
Okay? So we don't need this and not only that, what's going
to happen here when we do this
at sign property is objective-C is going to create that getter
and setter methods that I told you
about to set these contents automatically for us,
and we want them to be simple, okay?
This is what they're going to look like.
We want them to be simple.
If we don't say nonatomic, there's going to be all kinds
of locking code in there, right?
If you have multiple threads and you're allowing multiple threads
to access the setter and getter here,
then you need locking code, and we don't want locking code,
especially if we're going to implement the setter
and getter ourselves, which we're going to, sometimes.
Okay? But the default here is
that we don't implement this setter and getter,
it's automatically in there forest.
So you can see there's three parts to this.
There's the at sign synthesize, you see that?
That's basically just saying underbar contents is the name
of the instance variable
in which the property contents is going to be stored.
Now we could say at sign synthesize contents equals foo
[phonetic], and then contents property would be stored
in an instance variable called foo.
But that would be very confusing,
so we always use underbar name of the property.
Okay? And so that's part one,
just basically allocating an instance variable
to store this contents property.
Then there's the getter, that's NSString contents,
return contents, so the dash, parentheses,
NSString contents is a method declaration in objective-C,
the dash means this is a method,
parentheses NSString star means this is a method
that returns a pointer to a string,
and contents is the name of the method.
Okay? So the name of the method of the getter is the same
as the name of the property.
Then, the implementation is just return
that instance variable that we synthesized.
Okay? And similarly, the next method is a method
in objective-C for setting it.
And, again, dash [inaudible] method.
Parentheses void means this method does not return anything.
Okay? That's what parentheses void means.
Then set contents colon, that's the name
of this method, set contents colon.
Parentheses NSString star is the argument to this method.
Contents is just the name of the argument, the local name
of the variable in the local contents, context,
and the implementation is just underbar contents,
our instance variable equals that argument.
Okay? So, before I move on,
does everyone understand how these two methods are allowing
you to set and get an NSString storage space inside your card?
Everyone understand that?
Question? [Inaudible background question] Okay,
so the synthesize line, again, is just specifying the name
of the instance variable that we're going to use
to store this stuff in, underbar contents.
It's kind of weird, you could maybe, it might be better saying
at sign synthesize contents to use instance variable
with name, underbar contents.
That equals, I know, is a little weird.
It sounds like it's assigning something, but it's just,
that's what, think about equals as, you know,
we'll use the instance variable
with the name, underbar contents.
So that's what the synthesize is doing.
If you don't put the synthesize, it's not going
to create the space in your card instance, and it won't,
there won't be any name for it so you can't refer to it
in your getter and setter, okay?
Everyone understand this?
Any other questions?
Okay, now, the thing about it is, when you type the
at sign property on the left, this gets added to your
at sign implementation; however, you will not see it there.
[Pause] Okay?
So it's there, but you don't see it.
Okay, objective-C is, made it for you, but it doesn't show it
to you, but it's there, okay, that setter method
and that setter-getter method are there.
Okay? They exist.
And not only that, they're public, because you put
that at sign property declaration in your header file.
Everyone got that?
So let's look at another couple properties just
to see the syntax a little more.
So here's two properties that are bullions [phonetic].
Okay? There's no bullion primitive in C,
so objective-C has to find, typedef all caps BULL,
probably a short or something or an int or a char,
I don't know what, but you can think of it as a primitive type,
it's a boolean, it's value can either be yes,
which is some non-zero value, or no which is zero.
And these properties don't need the strong or weak.
Do you understand why that is?
Because they're primitive types,
they're not stored in the heap, okay?
They're just a int or a float, so there's no memory to manage
so you don't need to know about strong and weak pointers,
there's no pointers involved here,
this is just a BULL, a bullion.
So there's no strong or weak, but we still have the nonatomic,
because we still want the setter and the getter to be simple,
not having any locking code or any of that business.
So we're always going to have nonatomic
on every property in this class.
We will not have a single property in this entire class
that is not nonatomic.
So just put it in there, I wish it were the default.
Okay? So that's what we're going to do.
You can see we've synthesized them both
and we've got the setter and the getter for them both,
and this is all being done for us by objective-C.
Now, one thing that's kind of cool is we may not like the name
of this getter, because we want our code to read something
like if card is chosen, then do something.
If card is matched, then do something.
So we really want the getter called is chosen,
not just chosen.
You know, if card chosen, not as nice as if card is chosen.
So it's actually possible to rename the getter
by saying getter equals the new name you want.
Okay? And that's essentially renamed it, same thing,
we'll do the same thing with this one.
Getter equals is matched,
now that getter is called is matched.
And I bring this up because you're going
to see how iOS does this with bullion properties,
it tends to rename them to is this or has this,
depending on what the verb there is.
Okay? And again, objective-C is writing all this code on,
in the implementation, but you don't see it.
But it's there.
Okay? Now, [pause] we're going to talk
about why properties are good and why it's better
than just accessing instance variables directly,
[pause] in later lectures, but the bottom-line is it's good
for doing things like balance checking,
it's good for doing things like when you set a property
and you want to updated the UI.
It's doing good for things for initializing pointers.
Like that end string star contents property is going
to start off nil.
All properties, in objective-C, all of them, start off zero.
So for pointer, that's nil.
Okay? So that contents property, when we create a new card,
it's going to not point to any contents.
That cards going to be blank, okay, it's not going
to have anything on it.
So, it's nice to use the setter and getter,
we implement our own setter and getter that will check to see
if it's nil, and if it's not, and sometimes,
not with contents, but with some properties, if it's nil,
we'll create something in memory.
Okay? So that's another reason you use it.
So you'll see all these reasons why we want properties
in the next lecture basically.
Alright, so now, let's look at a method.
Okay? Just a regular, old method.
You've seen some methods, the setter and getter methods,
but what if we wanted to find our own method,
our own public method, so I'm going
to define this method called match.
Remember that I'm building a model here
for a card matching game, where I'm going to put all these cards
on the screen and the user is going to try and match them.
Pick ones that match, alright?
So I need a match method.
A method that tells me whether two cards match.
Okay? So, I'm trying to make this simple,
so I've made a simple match method
that has the following semantics.
It takes another card as the argument,
and it returns it an integer.
That integer is zero if the cards don't match, otherwise,
it's an integer that is higher, the better a match it is.
Okay? So like a really good match might be a thousand,
but a not so good match might only be a hundred, and,
or, or it could be one.
Now, the semantics of what that number is, totally depends
on the cards, because we're only going to match cards
against other cards, alright?
And we're going to find out how good a match they are
by how that, whatever that card class is, and we're going
to make a subclass of this class, called playing card,
that's going to give more points for matching the rank, okay,
than it is for matching the suit.
Okay? But that's up to subclasses of cards
to determine what the point system is, okay?
So, for our implementation of match, okay,
we're going to do a really simple implementation, so,
first let's assume that they don't match.
Okay, so I just made this local variable int score equals zero,
you can see that you can assign a variable,
actually all local variables also start out zero,
so I don't even really need that equals zero,
but I'm a big believer in putting that in
if that's really, you know, what you intend,
and in this case I intend the score to be actually zero.
The score of this match until I go and see
if these cards match, right?
So it's just a kind of programming style thing here.
So, how I'm going to tell, how am I going to tell
if this card that's been passed in match, matches the card
that it's being sent to?
And the answer is I'm going to send some messages, okay?
You see the open square brackets notation there,
that's the first time you're seeing me send a message
in objective-C, and I'm also sending two other messages
in this one line.
Card.contents and self.contents, you see both of those,
those are message sends, as well.
So there's two different syntaxes here
for sending a message.
One is open square brackets, okay, and we'll talk
about that one in a second.
And another one is dot notation, card.contents.
When do we use them?
We only use the dot notation for properties.
That's how we call the setter and getter
of properties, using dot notation.
Okay? Now, here we're calling the getter,
card.contents is calling the getter
of the contents property on the card instance.
Okay? How do we call the setter?
Exactly the same.
Card.contents, but we put it
on the left-hand side of the equals.
Card.contents equals, now we're calling the setter for contents.
You see? So here we're calling the getter.
We're also calling the getter
for contents on self, on our self.
So, in other language this might be called this, right,
but you know what self is, right, self is this instance
that this code is operating on.
So, we are going to compare these two strings, card.contents
and self.contents to see if they are equal and we are going to do
that with the NSString method is equal to string colon.
So [inaudible] equal to string colon can only be sent
to a string [pause], so is equal to string can only be sent
to a string and card.contents is a getter method
that returns a NSString, so we're good to go, right?
We're sending is equal string to a string, and the NS equal
to string takes as an argument, an NSString and, again,
self.contents is a getter method that returns NSString;
therefore, we have satisfied all the requirements of this equal
to string and we put square brackets around it,
and it's going to return a bullion is equal
to string is defined to return a bullion whether the contents
of those two strings are the same.
Notice we did not say equals equals.
Okay, we did not say card.contents equals
equals self.contents.
Because we'd just be impairing the pointers then,
not what the pointers point to, okay?
Everyone understand why we didn't use equals equals to see
if those two strings are the same?
So if those strings are the same,
I'm going to give one point, okay?
So this is either the dirt simple implementation of match,
which is if the cards are exactly the same,
their contents are exactly the same,
I'll get one point, otherwise I get zero.
Okay? Now we're going to do much better implementation in match
when we do playing card,
but this is our kind of dirt simple one.
Now, to give you just a little more about objective-C,
what if we changed this method, oh, so, yeah,
here's a little bit about who's the sender
and who's the receiver here.
You can look at this in the slides later.
Okay? But I'm going to make this a little more complicated.
I'm going to make the argument to match be an array of cards.
Okay? So now I'm matching this card that I'm sending this to,
to a whole bunch of other cards.
So now I'm going to need some new algorithm to match, right?
So, again, a playing card match,
if let's say you had matching three cards,
you might give a lot of points
if all three cards are the same rank, they're all jacks,
you get a lot of points.
If only two of them are jacks
and the other one is something else,
well you don't get very many points at all.
If they're all through the same suit,
you kind of get a medium amount of points, you see what I mean?
So, here I'm changing match to take an array
as the argument instead of just a single card.
And how would I change my implementation
to deal with that?
Well, I'm just going to put a four-loop around my if
and iterate through all the cards
and so this implementation, hopefully those of you
who are quick thinkers, you can know what this does,
this gives you one point
if the card that's receiving this matches any
of the cards in the array.
Any, not all, any.
Okay? Now you can imagine a lot better algorithms here.
Maybe you get one point for every card you match
in the array or you get two points for one match
and four points for two and eight points for three,
you know, some sort of binary thing, exponential point,
whatever, this is first day of lecture, we're just going
to give one point if it matches any, okay?
But mostly what I wanted to show you here is what it looks
like to have an array
as the argument instead of a single card.
So that you understand that the argument, what the argument
to the method is and also
so I can show you the four-loop there.
You see that four n [phonetic],
a lot of languages have that these days.
That just basically means it's a four-loop where it's going to go
through every object in that NS array and assign it to card,
card is the iteration variable, and execute that if once
for each of the cards in the array.
Everyone understand that?
If you have a question about that, ask?
No? Yeah? [Inaudible background comment] Oh, okay.
That's a great question.
So the question is if I just have that four-line,
but I said four card card,
not four card star card, in other cards, okay?
We'd get a syntax error.
Why? Because all objects are always pointed
to so we always have that star.
Okay? Always.
Alright? You can't have a card not being a pointer to it,
so the, you know, objective-C would give you a syntax error
there, it's impossible to not have that star.
Whenever you have the name of the class,
it's always going to have that star.
Question? [Inaudible background comment] Yes.
The question is, another great one,
can I use the square brackets to call the setter
and getter instead of using that dot notation?
And that's a really insightful question
and the answer is absolutely you can, it's perfectly legal,
because that setter and getter are completely normal methods.
There's nothing special about them whatsoever.
Okay? That dot notation is a nicety, syntactic sugar only.
The question is should you use square brackets for setter
and getter, and I think it's a matter of style.
You would definitely would want to be 100 percent consistent,
you would never want to mix them.
And I think most people,
most people would say use the dot notation.
It makes it clearer, it's a little simpler, nicer,
but, you know, you could.
In this class, please use the dot notation just
so I know you know how to use dot notation.
Question? [Inaudible background comment] Okay,
awesome question again.
Gosh, you guys are so good.
Can I use dot notation for a method that takes no arguments,
but is not a getter or a setter?
And the answer is objective-C will warn you about that,
not give you an error, but warn you,
and you should never do that in this class.
Okay? That is really not that good form,
whereas his question was kind of like you can argue,
that one, don't do it.
Okay? So. Use dot notations only for setters and getters.
Other questions?
Yeah?
>> How do you use a setter with dot notations?
>> So, yeah, question is how do you use a setter
with dot notation?
And it's exactly the same as a getter,
it's just that you're using it
on the left-hand side of an equals.
So card.contents equals, you know, A of clubs,
that would call the setter of contents, whereas, you know,
this is calling the getter, because it's not
on the left-hand side of the equal.
Okay? Excellent!
That's all I had today, so on Wednesday, we will do deck
and playing card and playing card and I'm going to dive right
into a big old demo of XCode 5
and show you how all this stuff is actually done,
and then next week we'll do, yet more objective-C.
Thank you very much!
>> For more, please visit us at stanford.edu.