Using Objective-C's method_invoke to call a vo

2019-07-13 04:56发布

问题:

On iOS, I'm attempting to use the method_invoke function from the Objective-C runtime (reference) in order to call an Objective-C method that is declared with a return type of void.

This works fine in non-ARC code, but with ARC enabled, I get a crash after the invocation of the method in objc_retain. I think what's going on is that the compiler notices method_invoke's return type of id, and attempts to retain the value returned by method_invoke (note that method_invoke is meant to return the return value of the method it invokes).

What's the correct way to let the compiler know that in this specific case, the return value of method_invoke is garbage and should not be retained? The following appears to work, but seems conceptually wrong:

(void)((__bridge void *)method_invoke(target, method));

This does not seem to work (still crashes in objc_retain:

(void)method_invoke(target, method)

Is there a more correct approach here?

回答1:

This question actually gave me the idea for a better solution.

The basic approach was to create a function pointer referencing method_invoke with the correct signature (void return type) and cast method_invoke into this function pointer, and then call through the function pointer.

So, roughly:

static void (*_method_invoke_void)(id, Method, ...) = (void (*)(id, Method, ...)) method_invoke;
... snip ...
_method_invoke_void(target, method);