When I began to learn Objective C, I often heard of people talking about "sending message", I was curious, come on, it's just calling a method.
Then I recalled that I had that same feelings when functions become to methods as I began to touch C++.
To support polymorphism, C++ object model has a vtable inside every object which stores instance methods addresses, by which, C++ has a little dynamic characteristic.
But those dynamic are settled after compiling to machine code, unlike ruby or python, which has a virtual machine to dynamically interpreter the behaviors of a program, you might know, the duck typing.
Like C++, Objective C is also compiled to machine code, it supports
polymiorphism, but also, to another level, it supports duck typing, you
can send messages to any objects even the
What does it do to make it possible?
A Simple Program
Let's do some tests by first creating a simple program.
Example is created, then a message is sent to
Producing assembly by
clang -S Example.m ->
The result is a little complicated. Generally speaking, it does three things.
First, setup necessary information, then make a call to
_objc_msgSend and store the return value to a local
Then we could jump to objc runtime source code to see what happens down the rabbit hole.
objc_msgSend is called during every message sending,
which might happen millions of times only by booting the Mac OS X
system, obviously, it needs to be fine tuned, no surprise, it is written
Although those are assembly, they're fairly readable by the good naming conventions and explainable comments.
NilTest macro, to check whether the
message sending target is nil, if nil, then returns nil, that's why we
could send messages to a nil object.
GetIsaFast to get the
Every objc object has a member named
isa, it's the
blueprint of an object, which has all objc runtime needs to inspect an
object and see what its class is and then seeing if it responds to some
CacheLookup, objc runtime searches for the
selector responsible for the message in a class method cache, and
invokes the selector to finish the work.
Since objc is a object oriented language, some objects may inheritant hundreds of methods, but only some are frequently called, it's not efficient to look up all the selectors every time a message is needed to be sent.
If objc runtime failed to find the selector for a message, it jumps to handle the cache miss.
MethodTableLookup will take the responsibility to
look up for the selector from the target
MethodTableLookup simply transfers the
Again, responsibility is transferred to
pay attention to the parameters assignments.
Finally, lookup is done, and cache is refilled.
If you want to step deeper, objc runtime source can be downloaded at this place.
At last, where do I find the objc runtime in the Mac OS X system?
Why am I so sure?
Since I lost my mind, wanted to remove the runtime to see what will happen.
First, Terminal stopped working, then Apps became irresponsible, no new App could be opened, and even can't reboot the whole system ...
Now I deeply know how important the objc runtime is in Mac OS X, and thank it, boot to recovery has a terminal to use, I was lucky.