Reputation: 4641
I'm trying to understand the difference between id objc_msgSend(id self, SEL op, ...)
and void objc_msgSend(void)
I have this macro that worked for methods of all types. However, when transitioning to arm64, this version of objc_msgSend is no longer available.
#define safePerformSelector(target, selector, ...) ([target respondsToSelector:selector] ? objc_msgSend(target, selector, ##__VA_ARGS__) : nil)
This is what I've come up with so far but it seems to only work for methods that return an object and fails for those that don't.
#define safePerformSelector(target, selector, ...) ([target respondsToSelector:selector] ? ((id (*)(id, SEL, ...))objc_msgSend)(target, selector, ##__VA_ARGS__) : nil)
Upvotes: 2
Views: 826
Reputation: 8012
You must always cast objc_msgSend()
to the correct function pointer type first. Type id(*)(id, SEL, ...)
is not the correct type, unless your method really does return id
and accept ...
(which IIRC is syntactically impossible).
If you call objc_msgSend()
with an incorrect function type then the called method may not receive parameter values correctly.
Upvotes: 3