iOS PerformSelector may cause a leak because its selector is unknown

来源:互联网 发布:百度网盘端口 编辑:程序博客网 时间:2024/05/28 19:23

开始的写法:

SEL selctor =NSSelectorFromString(_interaction.functionName);

[selfperformSelector:selctor withObject:nil];


解决办法: 

    编译器警告这个是由原因的,这种警告很少出现,甚至可以简单的忽略,而且解决也很容易.具体方法如下:

SEL selctor =NSSelectorFromString(_interaction.functionName);

IMP imp = [selfmethodForSelector:selctor];

void (*func) (id,SEL) = (void *)imp;

func(self,selctor);


解决的原因: 

    如果你调用一个方法名,那么就必须有与之对应的方法.你可以在运行时使用class_getMethodImplementation(比如说一个协议id<SomeProto>).只需要定义成(id (*IMP)(id, SEL, ...))格式这些函数指针就能调用的IMP.这可能最接近方法的实际签名,但并不完全的匹配.定义了IMP,你需要把他赋值给一个包含了所有ARC需要的参数(包括2个所有OC方法都会调用的隐式的参数self和_cmd)的函数指针 .第三行右边的(void *)只是告诉编译器我知道我要干什么,当指针不匹配的时候不要给我报错.最后一行就是调用你的函数指针.


警告原因:

    在ARC,运行时需要知道这个方法的执行结果.这个结果可能是void  int  char NSString * ,id  等.ARC通常从声明中获得你操作的对象的类型(释放不在使用的对象).


考虑在ARC中的4种返回值

1. 忽略非对象类型(void,int 等)

2.    Reture的对象,不用的时候会Release掉

3.    一个新的对象不再使用的时候Release掉

4.    对象的返回值在局部范围内有效(ns_return_autoreleased会在最里面的释放池释放的时候释放掉)


methodForSelector:的调用,假设这个方法被一个对象调用的时候有返回值,但是不retain或者release掉它.所有如果是第三者情况,就可能造成内存泄露.

对于那些没有返回值或者非对象的返回值的方法,你可以使用编译器特性忽略这个警告,但是这可能是危险的.所以即使你不想用它,编译器也会对其进行retain或者release.从编译器角度看,这毕竟是一个对象,这就意味着你调用方法,返回了一个非对象类型(包括void),这就可能会有一个垃圾指针被retain或者release.这就会导致崩溃.

0 0
原创粉丝点击