The Objective C Runtime Guide from Apple, states that you should never use objc_msgSend() in your own code, and recommends using methodForSelector: instead. However, it doesn't provide any reason for this.
What are the dangers of calling objc_msgSend() in your code?
Reason #1: Bad style - it's redundant and unreadable.
The compiler automatically generates calls to
objc_msgSend()
(or some variant thereof) when it encounters Objective-C messaging expressions. If you know the class and the selector to be sent at compile-time, there's no reason to writeinstead of
Even if you don't know the class or the selector (or even both), it's still safer (at least the compiler has a chance to warn you if you are doing something potentially nasty/wrong) to obtain a correctly typed function pointer to the implementation itself and use that function pointer instead:
This is especially true when the types of the arguments of a method are sensitive to default promotions - if they are, then you don't want to pass them through the variadic arguments
objc_msgSend()
takes, because your program will quickly invoke undefined behavior.Reason #2: dangerous and error-prone.
Notice the "or some variant thereof" part in #1. Not all message sends use the
objc_msgSend()
function itself. Due to complications and requirements in the ABI (in the calling convention of functions, in particular), there are separate functions for returning, for example, floating-point values or structures. For example, in the case of a method that performs some sort of searching (substrings, etc.), and it returns anNSRange
structure, depending on the platform, it may be necessary to use the structure-returning version of the messenger function:And if you get this wrong (e. g. you use the inappropriate messenger function, you mix up the pointers to the return value and to
self
, etc.), your program will likely behave incorrectly and/or crash. (And you will most probably get it wrong, because it's not even that simple - not all methods returning astruct
use this variant, since small structures will fit into one or two processor registers, eliminating the need for using the stack as the place of the return value. That's why - unless you are a hardcore ABI hacker - you rather want to let the compiler do its job, or there be dragons.)I can make a case. We use msgSend in one of our C++ files that's in a cross-platform project (Windows, Mac and Linux). We use it to ref count a reference in the backed (the shared code) that's used later to go from frontend to backend and vice versa. Very special case, admittedly.
You ask "what are the dangers?" and @H2CO3 has listed some ending with "unless you are a hardcore ABI hacker"...
As with many rules there are exceptions (and possibly a few more under ARC). So your reasoning for using
msgSend
should go something along the lines of:[ 1] I think I should use
msgSend
- don't.[2] But I've a case here... - you probably haven't, keep looking for another solution.
...
[10] I really think I should use it here - think again.
...
[100] Really, this looks like a case for
msgSend
, I can't see any other solution! OK, go readDocument.m
in the TextEdit code sample from Apple. Do you know why they usedmsgSend
? Are you sure... think again......
[1000] I understand why Apple used it, and my case is similar... You've found and understood the exception that proves the rule and your case matches, use it!
HTH