In C or any ECMAscript based language you 'call a public method or function' on an object. But in documentation for Objective C, there are no public method calls, only the sending of messages.
Is there anything wrong in thinking that when you 'send a message' in ObjC you are actually 'calling a public method on an Object'.?
Theoretically, they're different.
Practically, not so much.
They're different in that in Objective-C, objects can choose to not respond to messages, or forward messages on to different objects, or whatever. In languages like C, function calls are really just jumping to a certain spot in memory and executing code. There's no dynamic behavior involved.
However, in standard use cases, when you send a message to an object, the method that the message represented will usually end up being called. So about 99% of the time, sending a message will result in calling a method. As such, we often say "call a method" when we really mean "send a message". So practically, they're almost always the same, but they don't have to be.
A while ago, I waxed philosophical on this topic and blogged about it: http://davedelong.tumblr.com/post/58428190187/an-observation-on-objective-c
edit
To directly answer your question, there's usually nothing wrong with saying "calling a method" instead of "sending a message". However, it's important to understand that there is a very significant implementation difference.
(And as an aside, my personal preference is to say "invoke a method on an object")
Because of Objective-C's dynamic messaging dispatch, message sending is actually different from calling a C function or a C++ method (although eventually, a C function will be called). Messages are sent through selectors to the receiving object, which either responds to the message by invoking an IMP (a C function pointer) or by forwarding the message to its superclass. If no class in the inheritance chain responds to the message, an exception is thrown. It's also possible to intercept a message and forward it to a wholly different class (this is what NSProxy subclasses do).
When using Objective-C, there isn't a huge difference between message sending and C++-style method calling, but there are a few practical implications of the message passing system that I know of:
Since the message processing happens at runtime, instead of compile time, there's no compile-time way to know whether a class responds to any particular message. This is why you usually get compiler warnings instead of errors when you misspell a method, for instance.
You can safely send any message to nil, allowing for idioms like [foo release] without worrying about checking for NULL.
As #CrazyJugglerDrummer says, message dispatching allows you to send messages to a lot of objects at a time without worrying about whether they will respond to them. This allows informal protocols and sending messages to all objects in a container.
I'm not 100% sure of this, but I think categories (adding methods to already-existing classes) are made possible through dynamic message dispatch.
Message sending allows for message forwarding (for instance with NSProxy subclasses).
Message sending allows you to do interesting low-level hacking such as method swizzling (exchanging implementations of methods at runtime).
No, there's nothing at all wrong with thinking of it like that. They are called messages because they are a layer of abstraction over functions. Part of this comes from Objective C's type system. A better understanding of messages helps:
full source on wikipedia (I've picked out some of the more relevant issues)
Internal names of the function are
rarely used directly. Generally,
messages are converted to function
calls defined in the Objective-C
runtime library. It is not necessarily
known at link time which method will
be called because the class of the
receiver (the object being sent the
message) need not be known until
runtime.
from same article:
The Objective-C model of
object-oriented programming is based
on message passing to object
instances. In Objective-C one does not
call a method; one sends a message. The object to which the
message is directed — the receiver —
is not guaranteed to respond to a
message, and if it does not, it simply
raises an exception.
Smalltalk-style programming
allows messages to go unimplemented,
with the method resolved to its
implementation at runtime. For
example, a message may be sent to a
collection of objects, to which only
some will be expected to respond,
without fear of producing runtime
errors. (The Cocoa platform takes
advantage of this, as all objects in a
Cocoa application are sent the
awakeFromNib: message as the
application launches. Objects may
respond by executing any
initialization required at launch.)
Message passing also does not require
that an object be defined at compile
time.
On a C function call, the compiler replaces the selector with a call to a function, and execution jumps in response to the function call.
In Objective-C methods are dynamically bound to messages, which means that method names are resolved to implementations at runtime. Specifically, the object is examined at runtime to see if it contains a pointer to an implementation for the given selector.
As a consequence, Objective-C lets you load and link new classes and categories while it’s running, and perform techniques like swizzling, categories, object proxies, and others. None of this is possible in C.
Was taught this in my Java class. I would say they only have realistic differences in multithreaded scenarios, where message-passing is a very legitimate and often-used technique.
Related
I was going through an introduction to Smalltalk.
In C++, the functions declared inside a class can be called by objects of that class, and similarly in Smalltalk a keyword, termed as message, is written adjacent to the name of the object.
(Don't know much but would also like to ask here whether in response to a message a unique method is there to be executed?)
Basically, to my naive mind, this seems to be only a difference in syntax style. But, I wonder if internally in terms of compilation or memory structure this difference in calling holds any significance.
Thanks in advance.
P.S : I bow down to all of you for your time and answers . Thanks a lot.
The fundamental difference is that in Smalltalk, the receiver of the message has complete control over how that message is handled. It's a true object, not a data structure with functions that operate on it.
That means that in Smalltalk you can send any message to any object. The compiler places no restrictions on that, it's all handled at runtime. In C++, you can only invoke functions that the compiler knows about.
Also, Smalltalk messages are simply symbols (unique character strings), not a function address in memory as in C++. That means it's easy to send messages interactively, or over a network connection. There is a perform: method that lets you send a message given its string name.
An object even receives messages it does not implement. The Virtual Machine detects that case and creates a Message object, and then sends the messageNotUnderstood: message. Again, it's the object's sole responsibility of how to handle that unknown message. Most objects simply inherit the default implementation which raises an error, but an object can also handle it itself. It could, for example, forward those messages to a remote object, or log them to a file, etc.
You call a function in C++ because during the compilation time you know which function will be called (or at least you have a finite set of functions defined in a class hierarchy.
Smalltalk is dynamically typed and late bound, so during the compilation time you have no idea which method is going to be evaluated (if one will be at all). Thus you send a message, and if the object has a method with that selector, it is evaluated. Otherwise, the "message not understood" exception is raised.
There are already good answers here. Let me add some details (originally, part of this was in a comment).
In plain C, the target of each function call is determined at link time (except when you use function pointers). C++ adds virtual functions, for which the actual function that will be invoked by a call is determined at runtime (dynamic dispatch, late binding). Function pointers allow for custom dispatch mechanisms to some degree, but you have to program it yourself.
In Smalltalk, all message sends are dynamically dispatched. In C++ terms this roughly means: All member functions are virtual, and there are no standalone functions (there is always a receiver). Therefore, the Smalltalk compiler never* decides which method will be invoked by a message send. Instead, the invoked method is determined at runtime by the Virtual Machine that implements Smalltalk.
One way to implement virtual function dispatching is virtual function tables. An approximate equivalent in Smalltalk are method dictionaries. However, these dictionaries are mutable, unlike typical virtual function tables, which are generated by the C++ compiler and do not change at runtime. All Smalltalk behaviors (Behavior being a superclass of Class) have such a method dictionary. As #aka.nice pointed out in his answer, the method dictionaries can be queried. But methods can also be added (or removed) while the Smalltalk system runs. When the Smalltalk VM dispatches a message send, it searches the method dictionaries of the receiver's superclass chain for the correct method. There are usually caches in place to avoid the recurring cost of that lookup.
Also note that message passing is the only way for objects to communicate in Smalltalk. Two objects cannot access each other's instance variables, even if they belong to the same class. In C++, you can write code that breaks this encapsulation. Hence, message sending is fundamental in Smalltalk, whereas in C++ it is basically an optional feature.
In C++, Java, and similar languages, there is another form of dispatch, called function overloading. It happens exclusively at compile time and selects a function based on the declared types of the arguments at the call site. You cannot influence it at runtime. Smalltalk obviously does not provide this form of dispatch because it does not have static typing of variables. It can be realized nevertheless using idioms such as double dispatch. Other languages, such as Common Lisp's CLOS or Groovy, provide the even more general multiple dispatch, which means that a method will be selected based on both the receiver's type and the runtime types of all the arguments.
* Some special messages such as ifTrue: ifFalse: whileTrue: are usually compiled directly to conditional branches and jumps in the bytecode, instead of message sends. But in most cases it does not influence the semantics.
Here are a few example of what you would not find in C++
In Smalltalk, you create a new class by sending a message (either to the superclass, or to the namespace depending on the dialect).
In Smalltalk, you compile a new method by sending a message to a Compiler.
In Smalltalk, a Debugger is opened in response to an unhandled exception by sending a message. All the exception handling is implemented in term of sending messages.
In Smalltalk you can query the methods of a Class, or gather all its instances by sending messages.
More trivially, all control structures (branch, loops, ...) are performed by sending messages.
It's messages all the way down.
There are various Mac developer libraries which invoke certain implemented methods when a certain event occurs. For instance, there is an ImageCapture framework which has many methods pertaining to a protocol which a delegate implements like didAddDevice, didWindowLoad, etc.
My question is when the method is invoked, where does the control reach after that methods finishes execution. I ask this because the project which I am working on involves use of such frameworks where - after the invoked method finishes execution, the program such hangs there i.e. I am not certain where the control has reached. Can anyone suggest something?
Methods are invoked and return in Objective-C in a relatively ordinary way: When a method is to be called, a message is sent to the instance that should execute the method, consisting of the method name (which we call a selector), and pointers to the arguments and the caller (whom we call sender).
The important practical differences to how many other languages do this are:
Sending a message to nil does not result in a null pointer exception. It just gets quietly discarded, nothing happens, and you don't even get notified.
When an instance does not implement a selector, there are mechanisms in place that allow forwarding the message to other objects. This is rarely done, though.
You can ask an instance whether it implements a certain selector, and if it doesn't, choose not to send it a message (because that would crash).
So what happens in your concrete case?
The methods you are describing above get called on the delegate of the sender. They are likely optional, which means that if they are not implemented on the delegate (even though the delegate adheres to the protocol), the sender will see that they're not implanted and won't actually try to call them.
The other possibility is that you haven't set the delegate.
Looking only at the Objective-C runtime library, when a message is sent to an object that doesn't respond to it, the runtime system gives the receiver another chance to handle the message. So, the receiver's forward:: method, if implemented, gets called. However, looking at NSObject.mm, NSObject doesn't seem to implement forward::.
So, how does NSObject's forwardInvocation: method gets called, since the only thing the runtime system calls when a forwarding is needed is forward::? Does Foundation use objc_setForwardHandler (runtime.h) to set a new handler that calls forwardInvocation: whenever a message sent to a NSObject object needs to be forwarded?
At some point way back in time, there was no NSObject in the Objective-C runtime. When the language was first created by Brad Cox and Tom Love they added in a root object class, called Object. This implemented [Object forward::] , which was used to do message forwarding.
A few years later, NextStep came along and made their own additions to the language, creating the OpenStep framework (which became Cocoa). NextStep got rid of the Object class, and replaced it with NSObject. One of the changes that was made was to replace the forward:: method with forwardInvocation. The Object class is still kicking around in the source code (as you have found), but I'm pretty sure it's not available in either iOS or 64 bit OS X apps.
You are correct to suggest that objc_setForwardHandler is used to indicate that forwardInvocation should be used instead of forward:: for all NSObjects. I am afraid I'm not sure when Foundation calls this...I would guess at NSObject initialisation. I am also not massively up on the underlying runtime implementation, but hopefully that will have been of at least some help?
This SO post has a more detailed answer to your question as to what happen when a message is sent to an object that doesn't respond to it.
I've been writing various stuff using protocols as per example code, but also using some third party stuff, and they seem to adopt quite different approaches. Some specifically adopt the protocols in the interface using
#interface myClass <myProtocol>
others don't do that at all and merely pass themselves and are then set as delegates, but the end result seems to be exactly the same. I've tried both, and they both work fine. If someone was able to explain this I'd be a happy camper! Thanks very much.
A protocol declares a set of messages that an object must respond to (or with #optional, can respond to). In Objective-C, its only point (almost)* is to allow the compiler to flag up warnings if you pass an object that doesn't implement all the methods of the protocol with the correct signatures.
Taking a simple example: NSMutalbeDictionary has a method -setObject:ForKey: which sets the value for a particular key. The key is declared as type id which means you can pass any object and the compiler will not complain. However, the documentation for the method says:
The key is copied (using copyWithZone:; keys must conform to the NSCopying protocol).
so if you pass an object that doesn't have a -copyWithZone: method, you will get a exception at run time saying the key does not respond to -copyWithZone:. It would have been nice if the compiler could have detected your error.
If Apple had declared the method
-(void)setObject:(id)anObject forKey:(id<NSCopying>)aKey;
the compiler would have known about the requirement for -copyWithZone: (it's the only method declared in NSCopying) and would have caught any instances of passing incompatible objects at compile time. I think the reason they didn't do that is for backward compatibility. If bbum is reading, he might know the real reason why not.
*I say "almost" because you can test to see if an object conforms to a protocol at run time.
Objective-C can do both static and dynamic typing, so that protocols aren’t really required for the usual use cases. You can always type your delegate as id and then send it whatever messages you want. (The compiler will warn you if you attempt to send a message that’s not visible from the current file. That’s about the only sanity check it can do for id-typed objects without doing advanced type inference.)
But narrowing the id type down with protocols is nice and recommended, because 1) the code is more readable, 2) the compiler will warn you if you try to send the delegate some bogus message and 3) you’ll get better code completion.
Also the Xcode Code Sense can be very helpful if you use protocols. Sometimes it will suggest the missing methods.
While reading the documentation, I wonder if objc_msgSend() is actually the "core technology" in delivering the functionality for making Objective-C "object oriented". Maybe someone can explain in more detail which other pieces come into place to enable the object oriented paradigm of Objective-C?
Not entirely.
Objective-C is object oriented solely because it encapsulates data and functionality into a single container; a class.
That is pretty much all there is to "object oriented programming".
Now, there are many different kinds of object oriented programming and one critical aspect is whether or not a language uses dynamic or static dispatch.
In a statically dispatched language -- C++ is the best example (yes, I know it has virtual methods that give a form of dynamic dispatch) -- a method call is wired up at compile time and cannot change at runtime. That is, the implementation of the method that will be used to fulfill the method call is fixed during compilation and cannot change at runtime.
With a dynamically dispatched language like Objective-C, the implementation of the method that will be used to fulfill a method call is determined each time the method call happens. Thus, through the use of categories or the runtime's API, it is possible to change a method's implementation while an application is running (this is actually how Key Value Observation works, for example).
objc_msgSend() is the hook that does the dynamic dispatch. It takes a reference to an object or a class & a method name -- a selector or SEL, as it is called -- and looks up the implementation on the object or class that goes by that method name. Once the implementation is found, it is called.
If no implementation is found, objc_msgSend() will then take a series of steps to see if the class or instance wants to handle the unrecognized method call somehow, allowing one object to stand in for another (proxying) or similar functionality.
There is a lot more to it than that. I would suggest you read Apple's documentation for more information.
There's quite a bit more to it.