开始的写法:
SEL selctor = NSSelectorFromString(_interaction.functionName);
[self performSelector:selctor withObject:nil];
解决办法:
编译器警告这个是由原因的,这种警告很少出现,甚至可以简单的忽略,而且解决也很容易.具体方法如下:
SEL selctor = NSSelectorFromString(_interaction.functionName);
IMP imp = [self methodForSelector: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.这就会导致崩溃.