在写项目的时候,两个动作,同样的操作,但是传递不同的消息,就想到了[target performSelector:sell withObject:nil],写完后发现很正常,但是有个警告,本能的就觉得不舒服,仔细一看:performSelector may cause a leak because itsselector is unknown。
既然编译报警告,我们就不能不管。引起这个警告的原因是什么呢?
我们在调用这些方法的时候有可能返回的是void 或者其他 non-Objects,我们可以忽略这个警告,但是不建议这么做。我们知道oc的内存管理机制,有retain必然有release。在arc模式下,这些都由编译器帮我们做了。但是,假如我们的方法返回的是non-Objects(当然,包括void),这时retain或者release,我们的程序就有可能crash掉。
既然知道了原因,那么解决办法呢?
我们有两种解决办法
第一种:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector: sel withObject: nil];
#pragma clang diagnostic pop
也可以定义一个宏
#define SuppressPerformSelectorLeakWarning(Stuff) \
do { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
Stuff; \
_Pragma("clang diagnostic pop") \
} while (0)
SuppressPerformSelectorLeakWarning(
[target performSelector:sel withObject:nil]
);
这样使用起来更方便,但是这种方法并没有真正消除这个警告
第二种解决办法:
SEL selector = NSSelectorFromString(@"someMethod");
IMP imp = [_controller methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(_controller, selector);
还有另一种写法,不过读起来费力
SEL selector = NSSelectorFromString(@"someMethod");
((void (*)(id, SEL))[target methodForSelector:selector])(target, selector);
到此,这个警告算是完全消除了。
更加详细请移步:http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown