CrimsonChris
CrimsonChris

Reputation: 4641

objc_msgSend macro on arm64

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

Answers (1)

Greg Parker
Greg Parker

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

Related Questions