Also, the "call a method"/"send a message" distinction is useful. I don't usually criticize people for using the "method call" terminology, but I almost always use the latter since the idea of messages is central to a lot of Objective-C idioms (e.g. the responder chain in Cocoa). It's helpful to think in terms of messages.
Beyond that, I find that mentally framing your program as objects sending messages to each other and responding as they see fit just leads more naturally to good OO designs. It implies a lack of coupling that is absent from the semantics of a "method call."
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.
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.Yes they are similar, and most often sending a message of a particular name will invoke a method of that name via the messenger. But they are different in ways that matter, so it is better to use the correct terminology.
However, it's not really a big deal, you will typically be understood either way. However, I don't quite understand why using the correct terminology is so difficult. "Send a message" vs. "Call a method". Same number of words, same number of syllables. OK, 1 letter more to type...
A method is an implementation, something that executes. Protocols do not contain implementations, though there have been proposals to actually add methods to protocols. Talking about such a proposal to add methods to protocols becomes difficult when you have called the messages that are already there methods...
How would it definitely indicate that it returns an object? It has the same signature whether it's an accessor or a behavior, so you don't know if the implementation is returning an object.
That turns out not to be the case:
-(void)behavior;
-accessor;- (id)foo
reduces readability, while
-(id) foo
is much better.
I realize the first one is more common in Apple and is probably more standard, but it begs the question why such a horrible convention ever caught on.
-foo
is even better. :-)
-(void)foo;
This is how C and by extension, Objective-C work: to indicate "nothing" you have to put in something, specifically "void".