3

I‘ve read Apple's message forwarding document and other articles, and it seems the ObjC runtime will forward unrecognized messages for an object automatically, and if there isn't a matching selector, it will throw an "unrecognized selector sent to instance" error.

But I have two questions I can't explain.

  • How does the runtime find the next message forwarding object?
  • Can anyone explain the ObjC message forwarding chain?
jscs
  • 63,694
  • 13
  • 151
  • 195
johnMa
  • 3,291
  • 24
  • 37
  • 2
    you said you've read Apple's docs on message forwarding. It's explained there. It's explained even in Wikipedia – Andrey Chernukha Feb 24 '14 at 07:58
  • 1
    The runtime doesn't have to _find_ the forwarding object, an object has to provide it via `forwardingTargetForSelector:` Or you can forward it later, via `fowardInvocation:` It's up to each class individually. – jscs Feb 24 '14 at 08:01

2 Answers2

4

and it seems the ObjC runtime will forward unrecognized messages for an object automatically

You've misunderstood. The runtime doesn't find the "next" object, it calls the same object's forwardInvocation: method. You can implement that method in your class if you want an object to forward certain messages to some other object, such as a delegate.

Can anyone explain the ObjC message forwarding chain?

You might be confusing message forwarding and the responder chain. The two aren't related. Cocoa and Cocoa Touch both include a 'responder' class (NSResponder and UIResponder respectively) that creates a "chain" of objects starting from the "first responder." Responders pass messages that they don't implement on to the next responder in the chain. For example, menu commands in Cocoa often send their action messages to the first responder, which might be something like a text field or other UI element. If that object doesn't handle the action, it passes it on to the next responder, and so on until the message either is handled by some object, or it reaches the end of the chain (the application object).

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • I understand the purpose to implement `forwardInvocation` method, but I wonder did the system framework object implement this method as well? why can we use some method like `dismissViewController:animated:` to forward the response chain? – johnMa Feb 24 '14 at 08:08
  • [NSObject's `-forwardSelector:` calls `-doesNotRecognizeSelector:`](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#jumpTo_43). The reason that UIViewController forwards `-dismissViewController:animated:` to the presenting controller is that UIViewController defines a chain of objects, and that method is smart enough to pass the message on to the next object in the chain if it's sent to a view controller other than the presenting view controller. – Caleb Feb 24 '14 at 08:28
0

Consider you have an object obj. In runtime if message call happens to obj, your SDK calls

methodSignatureForSelector:

of your object(since any class inherited from NSObject methodSignatureForSelector:

is available for all object). If it returns NSMethodSignature object then your obj has implemented the selector if it is nil your SDK would make your app crash.

Rajesh
  • 10,318
  • 16
  • 44
  • 64