在Objective-C中需要以函数名或者函数指针来调用函数时,以回调函数为例,对象为(id)target,它的成员函数名为callback,之前习惯是这么写的:
if ([target respondsToSelector:callback]){ [target performSelector:callback withObject:nil]; }
但是在ARC下会报一个warning: PerformSelector may cause a leak because its selector is unknown
在网上查,很多人说的方法都是定义宏去ignore warning之类的。总感觉很不爽。今天查到了正确的解决方法:
【解决方法】
1. 比较好
if ([target respondsToSelector:callback]){
// [target performSelector:callback withObject:nil];
IMP imp = [target methodForSelector:callback];
void (*func)(id, SEL) = (void *)imp;
func(target, callback);
}
这样就不会报warning了。
2. 使用宏定义,忽略警告,也可以达到不报警的目的
在非ARC项目中没有这个警告。如果是在某一处修改只需要加入下列代码:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self.ticketTarget performSelector: self.ticketAction withObject: self];//此处是你调用函数的地方
#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:_action withObject:self]
);如果有返回值,可以按如下方式调用:
<span style="font-size:14px;">id result;
SuppressPerformSelectorLeakWarning(
result = [_target performSelector:_action withObject:self]
);</span>
本文介绍了在Objective-C的自动引用计数(ARC)环境下,如何避免使用performSelector时出现可能导致内存泄漏警告的问题。提供了两种解决方案:一是通过IMP获取函数指针并直接调用,二是使用宏定义来忽略警告。
812

被折叠的 条评论
为什么被折叠?



