问题描述
项目中使用到了从字符串创建选择器,编译时发现警告:"performSelector may cause a leak because its selector is unknown"(因为performSelector的选择器未知可能会引起泄漏),为什么在ARC模式下会出现这个警告?
经过搜索后,在Stackoverflow上发现了一个令人满意的答案。见 http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown 。
原因
在ARC模式下,运行时需要知道如何处理你正在调用的方法的返回值。这个返回值可以是任意值,如 void , int , char , NSString , id 等等。ARC通过头文件的函数定义来得到这些信息。所以平时我们用到的静态选择器就不会出现这个警告。因为在编译期间,这些信息都已经确定。
如:
[_renderer performSelector:@selector(someMethod)];
- (void)someMethod{
//code
}
而使用 [_renderer performSelector: NSSelectorFromString(@"release")]; 时ARC并不知道该方法的返回值是什么,以及该如何处理?该忽略?还是标记为 ns_returns_retained 还是 ns_returns_autoreleased ?
解决办法
1.使用函数指针方式
SEL selector = NSSelectorFromString(@"release");
IMP imp = [_renderer methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(_renderer, selector);
具体过程可以参考这篇文章:http://www.jianshu.com/p/a9569a9c9a63
反正我试试了他的上面的方法,但是没有任何效果
在这里我说下自己的见解:
项目采用iOS-ARC模式,系统在进入下一个控制器后返回上一个控制器时会自动调用#pragma mark - lifeCycleMethod
dealloc方法里的release,不用程序员自己再次手写release代码,若是写了反而会崩溃,直接在
#pragma mark - lifeCycleMethod
-(void)dealloc {
if(_renderer!=nil) {
// [_renderer release];
// [_renderer performSelector:releaseSelector()];
_renderer = nil;
}
就可以了,注释的地方不要加上去,谢谢🙏,最后直接让控制器里的类_renderer = nil就可以了;,不要问为什么,因为系统已经自动帮我们release了,之前一直用[_renderer performSelector:releaseSelector()];
////ARC下手动release
static SEL releaseSelector(){
return NSSelectorFromString(@"release");
}
这里的release实在是画蛇添足,惭愧。
若是你用的是MRC模式:
就需在
#pragma mark - lifeCycleMethod
-(void)dealloc {
if(_renderer!=nil) {
[_renderer release];
_renderer = nil;
[super dealloc];
}
最后ARC下的performSelector may cause a leak because its selector is unknown解决办法是:
只是对http://www.jianshu.com/p/2ff327a748d8
的崩溃的修复!!!