关于-performSelector的使用

在ARC项目中使用 performSelector: 函数出现“performSelector may cause a leak because its selector is unknown”这样的警告。这个问题的出现是因为在ARC模式下,运行时需要知道如何处理你正在调用的方法的返回值。这个返回值可以是任意值。所以平时我们用到的静态选择器就不会出现这个警告。因为在编译期间,这些信息都已经确定。

而使用 performSelector: 时ARC并不知道该方法的返回值是什么,以及该如何处理?该忽略?还是标记为 ns_returns_retained还是 ns_returns_autoreleased

一个有节操的程序员会在乎自己的代码的警告,就像在乎饭碗边上有只死蟑螂那样。


stackoverflow一位大神的文章是这样解决的:跳转

这种方式是一种方式,还有一种更方便有效的方法,我下面会讲到。

方法一:

这样即可;
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self performSelector:selector];
//#pragma clang diagnostic pop


可如果多处使用,定义为宏更方便:
#define SuppressPerformSelectorLeakWarning(code) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ code; \ _Pragma("clang diagnostic pop") \


 使用起来就比较简洁了:
 SuppressPerformSelectorLeakWarning([self performSelector:selector])

这是对#pragma 一个作用的展现,想了解更多关于 #pragma 在OC中的使用,请移步到我的这篇文章:

方法二:

SEL selector = NSSelectorFromString([NSString    stringWithFormat:@"forDrow%@",self.typeStr]);
IMP imp = [self methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(self, selector);

当有额外参数时,如
SEL selector = NSSelectorFromString(@"processRegion:ofView:");
IMP imp = [_controller methodForSelector:selector];
CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp;
CGRect result = func(_controller, selector, someRect, someView);

这个方法是使用函数指针的方法,算是比较底层的使用方法了。

参考:
'iOS performSelector may cause a leak' warning
performSelector may cause a leak because its selector is unknown"警告原因及其解决办法

你可能感兴趣的:(关于-performSelector的使用)