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.
Related
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.
Before ARC, I had an "X may not respond to xxx" warning, which is a pretty harmless warning which does not prevent it from compiling. Now, I am trying to convert my project to ARC, and I have an "No visible #interface for X declares the selector xxx" error, which prevents it from compiling.
I know exactly what I am doing, and why the warning was there, and I can tell you that the program is correct. Previously, the compiler compiled it with no problem, and should not now stop it from compiling.
It is true that class X's interface does not declare that selector, but X is a class that dynamically handles any message with any selector sent to it, using forwardInvocation: (that is one of the beautiful things about Objective-C), so its interface cannot possibly declare all the selectors that can be called on it. And the selector is declared somewhere, just not on X.
I know exactly what I am doing, and why the warning was there, and I can tell you that the program is correct.
OK -- Just use objc_msgSend et al. directly if you want to do the compiler's work.
It is true that class X's interface does not declare that selector, but X is a class that dynamically handles any message with any selector sent to it, using forwardInvocation: (that is one of the beautiful things about Objective-C), so its interface cannot possibly declare all the selectors that can be called on it. And the selector is declared somewhere, just not on X.
If it's too tedious to declare but not tedious enough to use in messaging that seems to contradict your program's use of the selector… Sounds like the dangerous territory of generated code with significant human intervention.
Perhaps you should consider declaring a protocol so the compiler can at least set the message calls up correctly for you -- and if you change or break something, it has a chance to adapt or notify you.
I'm not certain, but I believe under ARC it's more important that the compiler can see a method signature, because it needs to know what memory management is needed. So you'll either need to:
Declare the methods you're using via one of the normal methods (i.e. ideally on the real receiver, but if nothing else as a category, even if only on NSObject).
Do things manually via NSInvocation or some other similar means, taking full responsibility for memory management (which can be tricky, as you'll have to bridge to and from ARC).
Update: I just checked the clang source, and this is indeed the case - it needs the signature when using ARC. It's not just trying to be mean. :)
It is true that class X's interface does not declare that selector, but X is a class that dynamically handles any message with any selector sent to it, using forwardInvocation: (that is one of the beautiful things about Objective-C), so its interface cannot possibly declare all the selectors that can be called on it. And the selector is declared somewhere, just not on X.
Cast to id if you want to discard the static type information. Or if your object is a proxy for another class, maybe cast to that class.
So long as the method is declared somewhere in a header (which needed to be the case anyway), and there is no ambiguity with argument types, this should fix the error.
If you're interested in why this only is an issue with ARC enabled, check the answer to this question I asked: Why is 'no known method for selector x' a hard error under ARC?
I have been reading Apple's "The Objective-C Programming Language", I noticed that if you have say,
Class A /w methods MA and MB, where MA calls MB with "[self MB]".
If you subclass Class A, lets call it SubClass A, and over-ride MB. Made an instance of SubClass A and call MA, it will use the new MB. Now if you call "[super MA]" instead, it will still use the new MB.
Am I correct?
So I was wondering if "self" is the "right" way to go about this, calling other methods in the same instance, or if it's only used for special situations like covering initializers.
Yes, self is the right way to send a message to the same instance that the method is executing on.
One of the big things to keep in mind about the object model of languages like Objective-C is that, conceptually, you are not "calling methods" — you're sending messages. You're telling the object what to do, not how to do it. You shouldn't normally have to think about what precise method will execute when you send a message — the object is expected to respond appropriately. So if somebody has overridden this "MB" method, presumably the new behavior is how he wants the object to respond when it gets an "MB" message. If somebody has overridden "MB" such that it is no longer usable the way the old method was, then that sounds like a bug.
Yes it is.
Using self inside your class is the right way to go if you want to call methods that are in the same class.
'self' represents the current instance of the class where you are using it.
self is the right way to go. Every method in Objective-C can be thought of as "virtual" (in C++ parlance).
In SubClass A, you don't need to make an instance, you can access any function of subClass A by sing self.
making new object makes a new instance, so it reintialize all the property for that instance.
so you can't do any thing right with this.
self always be right for accessing same class methods and property.
Hope now you can understand why self rather than making other new instance.
And [super MA] must call method of class A's MA method, no case in which MB calls for calling MA.
I have test it, there is no bug all OOPs concept follow in objective c you can call super class method by calling method on super keyword.
So Probably you are doing some thing wrong. just check 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.
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.