performSelector (选择器,用于消息传递)
前段时间在使用performSelector时出现了以下警告:performSelector may cause a leak because its selector is unknown,于是上网搜了一下资料,了解了一下performSelector这个东西。
先来看看关于performSelector的调用方法:
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
以上三个方法只有参数不同,但最多只支持两个参数传递,当然多余的参数可以放到字典、数组里,这个不存在问题。
当调用我[target performSelector:action withObject:selfwithObject:arr];时,出现警告:performSelector may cause a leak because its selector is unknown,原因是arc下在编译期只确定消息名和参数数目,并不确定方法的地址,也不知道方法会返回什么,所以会出现警告。
解决办法:
1.宏定义忽略警告
#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:selfwithObject:arr];
);
当然这只能忽略而已
2.延时调用,但是多线程中想过去maybe会出问题,没测过
[targetperformSelector:actionwithObject:selfafterDelay:1];
3.函数指针调用,符合oc底层调用
(stackoverflow:http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown)
SELselector =NSSelectorFromString(@"someMethod");
((void(*)(id,SEL))[targetmethodForSelector:selector])(target, selector);
例如:((void(*)(id,SEL))[currentTargetmethodForSelector:currentAction])(message,currentAction);