写高质量OC代码52建议总结:42.多用GCD,少用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系列方法,而是把任务封装到块中,然后调用大中枢派发相关方法来实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值