4 ms·
How is that any different from calling a method on a known interface supported by an unknown object in a language such as eg. C# or Java?
by poizan42 13y ago
How is that any different from calling a method on a known interface supported by an unknown object in a language such as eg. C# or Java?
- chc 13y agoIf you're going through an interface, it sounds like you have to have a specific object in mind and you just don't know its class. In the pattern I'm talking about, you don't necessarily send the message to the object that will actually respond to the message. You send it to another object and the objects in the chain talk to each other until one agrees to handle it or the end of the chain is reached. This pattern can be used with classes that might not even implement the method. You can do something similar with C# or Java using reflection, but it is more natural in Objective-C.
- mikeash 13y ago> the objects in the chain talk to each other until one agrees to handle it This seems to be greatly overstating the complexity of what happens. There are two cases I can think of that this might describe. One is event messages. This is handled by having everything that can handle an event subclass from NSResponder. NSResponder is then full of little stub methods like this: - (void)mouseDown: (NSEvent *)event { [[self nextResponder] mouseDown: event]; } You then subclass NSResponder and override the methods you're interested in. This would look pretty much the same in any OO language with subclassing and inheritance, which is just about all of them. (NSResponder actually gets a bit clever here, and funnels these methods through a function call that handles general look-up-and-send logic, but the basic principle of what's going on is what you see above.) The other case is action methods with a nil target. Here, there's just a method that looks like this: - (void)sendAction: (SEL)action fromSender: (id)sender { for(id target = [self firstResponder]; target != nil; target = [target nextResponder]) { if([target respondsToSelector: action]) { [target performSelector: action withObject: sender]; break; } } } Again, the real implementation is a bit more clever, but that's the essential part. The use of reflection rules out C++, but it would look pretty much the same in Java. The inside of the loop in Java would look something like: try { Method m = target.getClass().getMethod(action, new Class[]{ Object.class }) m.invoke(target, sender); break; } catch(NoSuchMethodException e) {} The fact that action would have to be a String is a bit smelly, but overall it's pretty much the same code as the Objective-C version. The fact that this pattern isn't used in Java comes down to tradition and happenstance, not any sort of worse affinity on the part of the language.