Home > DeveloperSection > Forums > performSelector may cause a leak because its selector is unknown
ezra heywood
ezra heywood

Total Post:145

Posted on    April-25-2015 1:12 AM

 iPhone iPhone  Ios  Objective C 

 1 Reply(s)
 535  View(s)
Rate this:
I'm getting the following warning by the ARC compiler:
"performSelector may cause a leak because its selector is unknown".
Here's what I'm doing:
[_controller performSelector:NSSelectorFromString(@"someMethod")];
Why do I get this warning? I understand the compiler can't check if the selector exists or not, but why would that cause a leak? And how can I change my code so that I don't get this warning anymore?

Mayank Tripathi
Mayank Tripathi

Total Post:397

Posted on    April-25-2015 7:32 AM

The compiler is warning about this for a reason. It's very rare that this warning should simply be ignored, and it's easy to work around. Here's how:

SEL selector = NSSelectorFromString(@"someMethod");
IMP imp = [_controller methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(_controller, selector);
Or more tersely (though hard to read):

SEL selector = NSSelectorFromString(@"someMethod");
((void (*)(id, SEL))[_controller methodForSelector:selector])(_controller, selector)


What's going on here is you're asking the controller for the C function pointer for the method corresponding to the controller. All NSObjects respond to methodForSelector:, but you can also use class_getMethodImplementation in the Objective-C runtime (useful if you only have a protocol reference, like id<SomeProto>). These function pointers are called IMPs, and are simple typedefed function pointers (id (*IMP)(id, SEL, ...))1. This may be close to the actual method signature of the method, but will not always match exactly.

Once you have the IMP, you need to cast it to a function pointer that includes all of the details that ARC needs (including the two implicit hidden arguments self and _cmd of every Objective-C method call). This is handled in the third line (the (void *) on the right hand side simply tells the compiler that you know what you're doing and not to generate a warning since the pointer types don't match).

Finally, you call the function pointer.

Don't want to miss updates? Please click the below button!

Follow MindStick