有几个方法可以推迟执行方法调用,也可以指定运行方法。这些功能原来很有用,但是现在有个大中枢派发和块则应该避开。
-(id)performSelectoer:(SEL)selector
下面两行代码执行效果相同:
另一个原因是,返回值只能是void或者对象。浮点数或者整数就会需要复杂的转换。
performSelector还有几个版本可以传递参数:
performSelector还有可以延后执行选择子的功能,或者放在另一个线程上执行。
改用块就不受这些限制了。performSelector提供的线程功能可以用大中枢派发实现,延时执行可以用dispatch_after来实现,在另一个线程上执行可以用disoatch_sync或者dispatch_async来实现。
总结:
1.performSelector在内存管理方面容易有疏漏,ARC无法确认选择子是什么而执行相应的操作。
2.performSelector所能处理的选择子太过局限。
3.如果想把任务放到另一个线程上执行,最好不要用performSelector系列方法,而是把任务封装到块中,然后调用大中枢派发相关方法来实现。
-(id)performSelectoer:(SEL)selector
下面两行代码执行效果相同:
[object performSelector:@selector(selectorName)];
[object selectorName];
看上去这个方法有点多余,如果选择子是在运行期决定的,这个方法就很强大了。
SEL selector;
if( some condition ) {
selector = @selector(foo);
} else if (some other condition) {
selector = @selector(bar);
} else {
selector = @selector(baz);
}
[object performSelector:selector];
这种写法非常灵活,编译器只有到运行期的时候才知道选择子是什么,在ARC下编译器会报警告。因为编译器不知道要调用什么选择子,也就不了解其方法和返回值。就没办法运行ARC的规则执行内存管理操作。ARC用了比较谨慎的做法,不添加释放操作,但是这么做可能会导致内存泄漏。
SEL selector;
if( some condition ) {
selector = @selector(newObject);
} else if ( some other conditon ) {
selector = @selector(copy);
} else {
selector = @selector(someProperty);
}
id ret = [object performSelector:selector];
如果调用的是前两个方法,ret对象应该由这段代码来释放,第三个选择子无需释放。不用ARC,也要这样。使用performSelector产生的内存泄露即使静态分析器也很难侦测到。这是不推荐performSelector的原因。
另一个原因是,返回值只能是void或者对象。浮点数或者整数就会需要复杂的转换。
performSelector还有几个版本可以传递参数:
-(id)performSelector:(SEL)selector withObject:(id)object;
-(id)performSelector:(SEL)selector withObject:(id)objectA withObject:(id)objectB;
这些方法貌似有用但是有很多的局限性。传入的参数必须是对象(id),最多只能传两个参数。
performSelector还有可以延后执行选择子的功能,或者放在另一个线程上执行。
-(void)performSelector:(SEL)selector withObject:(id)argument afterDelay:(NSTimeInterval)delay;
-(void)performSelector:(SEL)selector onThread:(NSThread *)thread waitUntilDone:(BOOL)wait;
-(void)performSelectorOnMainThread:(SEL)selector withObject:(id)argument waitUnitlDone:(BOOL)wait;
这些方法同样很有局限性。这些方法都无法处理带有两个参数的选择子。需要把参数打包成字典,在调用方法里提取。
改用块就不受这些限制了。performSelector提供的线程功能可以用大中枢派发实现,延时执行可以用dispatch_after来实现,在另一个线程上执行可以用disoatch_sync或者dispatch_async来实现。
总结:
1.performSelector在内存管理方面容易有疏漏,ARC无法确认选择子是什么而执行相应的操作。
2.performSelector所能处理的选择子太过局限。
3.如果想把任务放到另一个线程上执行,最好不要用performSelector系列方法,而是把任务封装到块中,然后调用大中枢派发相关方法来实现。