Objective C message dispatch mechanism [closed] - objective-c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 months ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am just staring to play around with Objective C (writing toy iPhone apps) and I am curious about the underlying mechanism used to dispatch messages. I have a good understanding of how virtual functions in C++ are generally implemented and what the costs are relative to a static or non-virtual method call, but I don't have any background with Obj-C to know how messages are sent. Browsing around I found this loose benchmark and it mentions IMP cached messages being faster than virtual function calls, which are in turn faster than a standard message send.
I am not trying to optimize anything, just get deeper understanding of how exactly the messages get dispatched.
How are Obj-C messages dispatched?
How do Instance Method Pointers get cached and can you (in general) tell by reading the code if a message will get cached?
Are class methods essentially the same as a C function (or static class method in C++), or is there something more to them?
I know some of these questions may be 'implementation dependent' but there is only one implementation that really counts.

How are Obj-C messages dispatched?
Objective-C messages are dispatched using the runtime's objc_msgSend() function. Shown in the Apple docs, the function takes at least 2 arguments:
The receiving object
The selector of the message
[A variable list of arguments to the message being sent.]
Instances of a class have an isa pointer, which is a pointer to their class object. The selectors of methods in each object are stored in a "table" in the class object, and the objc_msgSend() function follows the isa pointer to the class object, to the find this table, and checks whether the method is in the table for the class. If it cannot find it, it looks for the method in the table of the class's superclass. If not found, it continues up the object tree, until it either finds the method or gets to the root object (NSObject). At this point, an exception is thrown.
How do Instance Method Pointers get cached and can you (in general) tell by reading the code if a message will get cached?
From Apple's Objective-C runtime guide on Messaging:
To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used. There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class. Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again). If the method selector is in the cache, messaging is only slightly slower than a function call. Once a program has been running long enough to “warm up” its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.
As stated, caching starts to occur once the program is running, and after the program has been running long enough, most of the method calls will run through the cached method. As it also says, the caching occurs as the methods are used, so a message is only cached when it is used.
Are class methods essentially the same as a C function (or static class method in C++), or is there something more to them?
Class objects handle method despatch in a similar manner to that of instances of classes. Each class object has an object that stores its own class methods, in an object called a metaclass. The class object has its own isa pointer to its metaclass object, which in turn has super metaclass objects, which it can inherit class objects from. Method dispatch to class methods is as so:
The dispatch system follows the class object's isa pointer to the metaclass object
The metaclass object's method table is searched for the class method.
If not found, the search continues to the metaclass object's superclass, where the search continues.
This process repeats until either the method is found, or until it gets to the root metaclass, and an exception is thrown.

Dispatch mechanisms
It is used to find a necessary executable code when method was called(message sent)
Inline
Static(Direct)(C, Java final, C++ default, Swift static, final) - compiler knows the necessary method realisation at compile-time.
Dynamic - is based on witness table(virtual table, dispatch table) and it introduce polymorphism
Table, V-Table(C++ virtual, Java default, Swift default) - Every object has a reference to class which has a table with all method addresses(super, overrides, new). SIL contains vtable or witness_table
Message(Objective-C, Swift dynamic) - Every object has a reference(isa) to class which contains a reference to superclass and dispatch table(which contains only realised methods(new and which were overhead)) and don't contain methods from super. If method was not found in current dispatch table, it continue searching in superclass's dispatch table. This process is optimised by caching. SIL contains volatile
Objective-C Message Dispatch
For example
class A {
func foo1() {}
func foo2() {}
}
class B: A {
override func foo2() {}
func foo3() {}
}
Objective-C obc_msgSend
id obc_msgSend(id self, SEL op, ...)
// self - object which receive a message
// op - selector of method
//... - arguments
If method implementation was not found for given selector you see next error
unrecognized selector sent to instance

Related

Pharo Smalltalk - How can I check if a message conforms to a protocol defined in another object's Class?

I'm looking at this form an Objective-C background so be gentle. The experiment looks like this:
Object1 has an instance variable named delegate.
Object1 receives a message and the proceeds to check if delegate implements a specific protocol (whose name is known beforehand), if it does, then it checks if the message is among the protocol's implemented methods. It then makes a decision on how to interact with the delegate and so on.
In Objective-C one has to define clear Protocols, usually stored in different files, and conforming to a protocol is checked by the compiler. In Pharo I can't seem to find how to check for this kind of information even though the Browser has a whole column dedicated to protocols, and beside grouping methods they seem to do very little.
Here are some few alternatives that could help you with this:
Get the collection of all selectors that populate the object's class:
anObject class selectors
Get the collection of all selectors that populate the object's class and all its superclasses:
anObject class allSelectors
Ask the class whether it implements a given message (for its instances):
anObject class canUnderstand: #putTheSelectorHere
Ask the object whether it understands a given message:
anObject respondsTo: #methodSelectorHere
Use the MessageNotUnderstood mechanism:
(see explanation below)
In 1 and 2 above you can use the returned collections to check whether they include a certain selector you are interested in. Features 3, 4 and 5 have a more dynamic nature. For example, you can refine the #doesNotUnderstand: method in your class as follows:
MyClass >> #doesNotUnderstand: aMessage
(delegate respondsTo: aMessage selector)
ifTrue: [^delegate
perform: aMessage selector
withArguments: aMessage arguments].
^super doesNotUnderstand: aMessage
This way, if your object receives a message that it does not understand, it will first receive the #doesNotUnderstand: message (without you having to do anything for this to happen) and here you could decide (e.g., by using the #respondsTo: message) whether to delegate it or not. If not, you can just relay on the default behavior (super doesNotUnderstand:) which would signal de MessageNotUnderstood exception.
Of course, there is a 6th option, which would be for the sender of the message to handle the MNU exception, but I don't think this is what you are looking for here.
There is the proxies work in Ghost/Marea and the original Smalltalk wrappers to the rescue I'm not sure the proxies have been updated for the latest Pharo version. Latest ghost version seems to be here

How does objective-c handle method resolution at run-time?

I've read here recently that an objective-c object is stored on the heap as a struct. The struct contains the objects iVars, inherited iVars, and the isa pointer.
I'm trying to figure out when I send a message to this object, how does the run-time figure out the code to run?
I know there is a class object for each class. Is this also stored on the heap?
I think the way it works is that the run-time gets the isa pointer from the struct, uses this to call the message on the class object. Is this correct?
In short, every Objective-C instance has a pointer to its class. The class contains an inventory of metadata that includes all the methods that the class implements. When a message is sent to an object -- when a method is called -- the runtime uses the pointer to the class to lookup the method by name and call it, if it can be found. If it isn't found, the runtime looks to the superclass (which is a part of each class's metadata) on up the inheritance chain to NSObject. If the method ultimately can't be found, the runtime goes through a series of last ditch efforts to see if their is an alternative handler and eventually raises an exception, if not.
If you want more detail than that, I wrote up a multipart tour of exactly how Objective-C method dispatch works. It is slightly out of date -- doesn't deal with ARC, tagged pointers or blocks-as-IMP -- but still fully applicable.
Yes, classes are stored in the heap, but generally not in malloc()d memory. Classes are generally loaded as read-only, shared, memory. That is, there will be only one copy of the NSString class in memory for all applications running on the system. You can dynamically create classes on the fly and these will be in the regular heap, but it is atypical.

Objective-C Find all init (constructor methods)

using the "Method * class_copyMethodList(Class cls, unsigned int *outCount)" function one can get a list of all methods that exist on an objective-C class.
I would like to know how to find which of these methods are constructors as I am writing an IOC container. I would like to determine the constructors and their parameter types.
I would like to know how to find which of these methods are
constructors as I am writing an IOC container. I would like to
determine the constructors and their parameter types.
In short, you can't. Or, at the least, you'll find that down this path lies madness.
First, Objective-C does not have constructors. It has initializers, sometimes many, and -- for a properly written class -- only one of which is the designated initializer. There is no way to identify the designated initializer at compile time or run time.
How do I use this with a Method * and no instantiated member of the
class?
You don't. First you allocate an instance of the class, then you initialize the instance.
Overall, this level of abstraction just isn't done in Objective-C outside of academic investigations. It can be done, but it is generally avoided because of the fragility of the resulting solution and the hairball of code-hell that is trying to dynamically support the underlying C ABI (go look at the source to libffi).
If you want to go down this path, then you are far better off either defining a custom abstract class that all of your containers will subclass that can provide the binding logic to the class behind it.
Or use protocols; i.e. a class could implement an IOCBean protocol and one method would be initIOCGoop that is the designated initializer goo.
Doing this generically for all classes is going to be rife with fragility, special cases, and will require a gigantic mess of code that will be difficult to maintain over time.
You can get the method signature by using the following method:
methodSignatureForSelector:
From the documentation:
An NSMethodSignature object records type information for the arguments and return value of a method. It is used to forward messages that the receiving object does not respond to—most notably in the case of distributed objects. You typically create an NSMethodSignature object using NSObject’s methodSignatureForSelector: instance method (on Mac OS X v10.5 and later you can also use signatureWithObjCTypes:). It is then used to create an NSInvocation object, which is passed as the argument to a forwardInvocation: message to send the invocation on to whatever other object can handle the message. In the default case, NSObject invokes doesNotRecognizeSelector:, which raises an exception. For distributed objects, the NSInvocation object is encoded using the information in the NSMethodSignature object and sent to the real object represented by the receiver of the message.

What's the difference between a method and a selector?

What the difference between a method, a selector and a message in Objective-C?
This is a great question.
Selector - a Selector is the name of a method. You're very familiar with these selectors: alloc, init, release, dictionaryWithObjectsAndKeys:, setObject:forKey:, etc. Note that the colon is part of the selector; it's how we identify that this method requires parameters. Also (though it's extremely rare), you can have selectors like this: doFoo:::. This is a method that takes three parameters, and you'd invoke it like [someObject doFoo:arg1 :arg2 :arg3]. There's no requirement that there be letters before each part of the selector components. As I said, this is extremely rare, and you will not find it used in the Cocoa frameworks. You can work with selectors directly in Cocoa. They have the type SEL: SEL aSelector = #selector(doSomething:) or SEL aSelector = NSSelectorFromString(#"doSomething:");
Message - a message is a selector and the arguments you are sending with it. If I say [dictionary setObject:obj forKey:key], then the "message" is the selector setObject:forKey: plus the arguments obj and key. Messages can be encapsulated in an NSInvocation object for later invocation. Messages are sent to a receiver. (ie, the object that "receives" the message).
Method - a method is a combination of a selector and an implementation (and accompanying metadata). The "implementation" is the actual block of code; it's a function pointer (an IMP). An actual method can be retrieved internally using a Method struct (retrievable from the runtime).
Some other related things that you didn't ask for:
Method Signature - a method signature represents the data types returned by and accepted by a method. They can be represented at runtime via an NSMethodSignature and (in some cases) a raw char*.
Implementation - the actual executable code of a method. Its type at runtime is an IMP, and it's really just a function pointer. iOS 4.3 includes a new ability to turn a block into an IMP. This is really cool.
One of the fun things to realize is that the name of a method (the selector) is distinct from the implementation of the method (the IMP). This means that you can swap them around, if you're feeling daring. You can also add and remove methods at runtime, because all you're doing is editing an entry in a hash table: the key is the selector, and the value is the IMP of the method. This allows you to do some really crazy and trippy stuff. It's not for the faint of heart. :)
A method is the implementation which is run when an object or class is asked to perform some action. It is in the scope of its containing class and is therefore different when referenced through some other class. A selector is an identifier which represents the name of a method. It is not related to any specific class or method, and can be used to describe a method of any class, whether it is a class or instance method.
Simply, a selector is like a key in a dictionary. It can tell you what method someone is talking about, but only if you also have the dictionary itself (the class or object). The method is what you get when you ask for the value from the dictionary using the selector as a key.
This site has a good overview of all the terminology in question: http://www.otierney.net/objective-c.html
Check out the link, but I'll give a quick summary:
A method is essentially like a method of function that you are used to in your favourite programming language.
A message (from the article) "A message can be dynamically forwarded to another object. Calling a message on an object in Objective-C doesn't mean that the object implements that message, just that it knows how to respond to it somehow via directly implementing it or forwarding the message to an object that does know how to."
Selectors can mean two things. It can refer to the name of a method, or "refers to the unique identifier that replaces the name when the source code is compiled. Compiled selectors are of type SEL." (from: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocSelectors.html)

'Calling a method' OR 'sending a message' in Objective C

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.