Reason # 1: Bad style - it's redundant and unreadable.
The compiler automatically generates objc_msgSend() calls (or a variant thereof) when detecting Objective-C message expressions. If you know that the class and selector must be sent at compile time, there is no reason to write
id obj = objc_msgSend(objc_msgSend([NSObject class], @selector(alloc)), @selector(init));
instead
id obj = [[NSObject alloc] init];
Even if you donβt know the class or selector (or even both), it is still safer (at least the compiler has a chance to warn you if you are doing something potentially unpleasant / wrong) to get a correctly printed function pointer to the implementation itself and use this function pointer instead:
const char *(*fptr)(NSString *, SEL) = [NSString instanceMethodForSelector:@selector(UTF8String)]; const char *cstr = fptr(@"Foo");
This is especially true when method argument types are sensitive to default promotions - if they exist, then you do not want to pass them through the objc_msgSend() variable arguments, because your program will quickly call undefined.
Reason # 2: Dangerous and error prone.
Pay attention to the part "or some variant" in # 1. Not all messages are sent using the objc_msgSend() function objc_msgSend() . Due to the complexity and requirements in the ABI (in particular, in the calling function convention), there are separate functions for returning, for example, values ββor floating point structures. For example, in the case of a method that performs some kind of search (substrings, etc.), and returns an NSRange structure, depending on the platform, it may be necessary to use the function version returning the structure of the message:
NSRange retval; objc_msgSend_stret(&retval, @"FooBar", @selector(rangeOfString:), @"Bar");
And if you make a mistake (for example, you use an inappropriate messenger function, you mix pointers with return value and self , etc.), your program will probably behave incorrectly and / or crash. ( And you are most likely mistaken, because it is not even so simple - not all methods that return a struct use this option, since small structures will fit into one or two processor registers, except for using the stack as the place of the return value. Therefore, if you are not an ABI hardcore hacker, you probably want the compiler to do its job, or there were dragons there.)