0:00
[MUSIC]
In this lecture, we're gonna talk a little bit about message passing,
passing messages.
Now we've been jumping around a little bit.
We've been talking about heat memory.
We've been talking about pointers.
Before that we were talking about objects.
Now we're gonna be talking about passing messages.
Passing messages is a way that developers communicate with objects.
And all of these things are gonna come together in the creation and
usage of objects.
So when you use objects and when you pass messages around you need to both know
about the heat memory, you have to know about how those objects are defined so
that you can then pass the messages.
And ultimately, so that you can use the objects.
So I know we've been covering a couple different threads as we've been
progressing through the lessons here, but they're coming together here shortly.
And the next thing we need to talk about is passing messages.
So, at a High-Level with Objective-C objects, unlike the underlying
C functions where you call functions, you don't do that with Objective-C objects.
Instead, what you do is you send messages.
You send the messages and that causes the object's methods to be executed.
In order to send these messages and thereby getting the methods to be executed
you need to use a special syntax that is appropriate for objects in objective C.
So let's remember for a second what our MyTime object looked like
by looking at the interface for it here.
1:41
If you recall we had to find six different properties one for
each of six different integers representing a particular time and date.
We had year, month, day, our minutes, seconds, and
then we defined a couple functions that we were just messing around with.
Which calculated the approximate seconds in some date.
And approximate seconds since 1970 in particular since this is the foundation of
one of our time calls that you may have learned about in the future.
And we're gonna add another one now called secondsSinceMidnight, and that'll just
calculate how many seconds it's been since midnight, regardless of the day.
2:22
This object has three different methods that are defined.
In order to send messages to this object we're going to use a particular pattern.
That pattern is defined by two square brackets and then two components.
The first component is the receiver.
And the second component is called the selector.
Now the receiver can be kind of one of two different things.
It can be an object's class name.
For example, MyTime.
In this case the receiver is the definition of the class.
3:42
On the other side, on the right side of this square bracket we have a selector.
And a selector is the name of the method that you want to invoke.
A method that Objective-C provides automatically so
some of the methods that you might call.
Some of the messages that you might send
4:09
The other thing that a selector could be, could be the name of a method
you've provided, that you've manually declared and defined.
So an example of a built in message is one called alloc.
And alloc is short allocation and it's an analogue to the malloc function we saw.
4:42
So what that would look like is maybe something like this.
Rather than using malloc to allocate an object on the heap
we're gonna use the built-in message called alloc.
So you might've thought, given what we've talked about before, that if
you wanted to create a MyTime object, a pointer to a MyTime object, like *a here.
*a is a type pointer to MyTime,
then you might call the malloc function with the size of MyTime.
This kinda seems correct.
And more or
less, it is following the pattern of the syntax that we've talked about.
It's just that objects have different rules that they're following,
that are built into the language.
So, instead of doing this, what we're gonna do is what's right below it.
5:24
On the left side of the equals sign is a variable a,
who's type is still pointer to MyTime.
But on the right we're gonna use the message passing syntax.
We've got the two square brackets.
On the left side we have the receiver, which is the class MyTime.
And on the right side we have the message alloc.
And what this is gonna do is it's gonna send the alloc message to
the MyTime class and it is going to reserve from the heap a chunk of
memory big enough to hold one MyTime object.
And it's going to return a pointer to that piece of memory and
a will be assigned the pointer to that piece of memory.
So that's gonna allocate MyTime-sized chunk of heap memory for you.
And that's the correct way to do it instead of with malloc.
6:13
So, an example of possibly calling in alloc,
sorry this is the components of the command to call malloc.
You have MyTime, and notice that this is the class name and
this isn't an instance variable and on the right you have alloc which is the message.
It is the selector and in this case the selector is
the pre-defined message that you're sending to the class.
So here's an example of a custom message.
So this is one that you might manually define.
6:54
If you are going to send an instance method,
you need a pointer to an object that has already been defined.
So in this example, What we'll do is we'll first use the alloc message in order to
create a heap chunk for my time.
And then, if we wanted to send a message to *a we reduce the square
backing syntax and on the left instead of spread in my time, we put the variable A.
7:20
And on the right, we would set put the message that we want to send in,
in this case, it's secondsSinceMidnight.
That would cause the secondsSinceMidnight method
7:45
In this call, a is the variable that points to a valid object,
it has to point to a valid object or you'll get an error.
For example, an example of a that does not point to a valid object
is if you set a equal to zero or null or nil.
8:01
And on the right is the method, and that method was defined in the .m and
.h and .m files.
Okay, now, defining and
calling methods that have parameters requires careful attention to the syntax.
In fact, this is one of the things that I had a hard time when I was first learning
objective C understanding the syntax for.
So what we are going to do is we're going to add a method to our MyTime object
that takes three parameters.
So our selector is going to be a message that sends three parameters to our object,
to our receiver.
8:36
Let's say it's gonna add the three numbers to the number of hours that's contained
in the object, and it returns the result.
Maybe you might do something like this in order to deal with timezones,
to convert from one timezone to another.
8:48
Maybe, it's still a little bit of a toy example.
So let's write that out.
We'll start with a very basic function that has main defined and not much else.
And after we have that specified, we can go ahead and
start adding some components to it.
Oops.
We can go ahead and start adding some components to it.
9:43
and then we will use the message passing syntax with square brackets.
We will send the message to our time instance
and the name of the selector is going to be add some
parameters:secondparameters:thirdparamete- rs:.
And the three numbers that we're going to send it are one, two, and three.
10:04
So meantime if you go up to the header, you can see that we haven't defined it yet
and we need to define it.
So first what we'll do is we'll declare this method here.
And we're gonna do it by specifying the return value, which is an int.
[INAUDIBLE] Type is an int.
Specifying the name, add some parameters.
And then, using a colon in order to indicate
the variables that are going to be included.
So, our first variable is gonna be an integer.
Were gonna call it a, locally.
And then we're gonna continue the name of the method as secondParameters :, and
the secondParameter locally will be called b, and it will be of type int.
Continue the name of our selector as thirdParameter :.
And the thirdParameter will be an int of type c.
10:47
And then, we'll go into the implementation of our class, and
we will add the function that implements that.
And we'll do that by repeating the method declaration and add some parameters,
with those three parameters specified there.
Within the body of the function,
we're gonna create a local variable called answer to hold our answer.
We will set answer,
initially to the number of hours that is in the local instance variable hour.
And then we'll just one by one go through and
add each of the different variables that were passed to us before returning it.
11:35
And we'll reformat it to sort of demonstrate good formatting practice
once everything's defined.
When we run it, what we will see is we'll see that the hour equal to 10, and
then when we add those parameters, we should add to 10 the number 1,
the number 2, the number 3.
And if all goes well when we print out the answer, the answer will be equal to 16.
Let's finish putting in the output line,
and run it with an output line, and see that we do, in fact, get the answer 16.
Which is what we would hope we would get.
All right, now the thing is, is this syntax is still confusing.
Methods that have parameters have a definition where we define which
parameters they take, and then they have the execution.
The point at which we actually send the message.
So we'll start in the definition, we'll show here that the method
name addSomeParameters has a name that's been split into pieces by the Parameters.
So the first part of the name is addSomeParameters:,the second
part of the name is secondParameter:, and
the third part of this method name is thirdParameter:.
So when we call this method by using a selector,
we have to specify all three of those.
13:02
Right after the colon,
we have the definition of the variable that's gonna be accepted.
So we have int a, type, and a local variable name type, and
a local variable name type and a local variable name.
Every colon is followed by exactly one parameter.
13:22
When it comes time to send the message, we need a pointer to the object,
in this case time.
That's the receiver.
And then the selector consists of all three of those components.
Of the method name with the colon, and then for each colon,
there's a parameter that has to be put into the middle of that selector name.
13:46
The first parameter that all three of those things form the select name.
When you send the message, as I said, you must use the entire selector name,
with parameters in the middle, one following each colon.
In this case the value of one will get copied to the local variable
a when the method gets called.
The value of two will get copied to the local variable b and
the value of three will get called to the local variable (int)c.
The text second parameter and
the text third parameter are optional, that text doesn't need to be there.
14:26
But what that text is often used for is a way of describing integer b and
integer c, so you know semantically what kind of data is supposed to be passed.
While second parameter and third parameter are optional, that text,
if you actually want a second and third parameter you must include the colons.
So it's okay to leave secondParameter but
there must be a colon if you want a second parameter.
It's okay to remove the text thirdParameter,
but you have to have the colon if you want to include a third parameter.
And then down when you call the text, when you call this method by using a selector,
just secondParameter would be missing, and thirdParameter would be missing, but
the colons in front of the 2 and 3 would remain.
Those colons become part of the method name.
So in summary, objects can receive messages.
A message invokes a method and a selector determines which message is sent.
Methods can be provided by the compiler; we saw that with Alec for
example and we'll talk more about which ones are provided automatically and
where they come from later.
Or they can be written by a programmer.
For example, the seconds since midnight one that we calculated.
Finally, methods that have parameters have selectors as well.
And those selectors have one colon for each parameter that they're sending.
And they may have additional pieces of their name,
which are split up by parameters that are put in the middle in order to try and
provide a way for semantically identifying what kind of data should be passed for
each of those parameters.
Okay, that's a quick introduction to message passing and we're gonna see that
as the common practice for interacting with objects in the future,
as we continue working towards developing our own apps.
[MUSIC]