转载

iOS GCD~performSelector、dispatch_once、NSOperation总结

一、使用GCD 替代 performSelector 系列方法

NSObject 的 performSelector 系列方法有很多限制。传给要执行的方法的参数的数量是有限制的,也没法方法保证能正确地取得要执行的方法的返回值。这些限制在使用 block 的 GCD 中都不存在。

下面是使用 GCD 替代 performSelector 的例子。使用 performSelector 系列方法:

[selfperformSelector:@selector(cake)
withObject:nil
afterDelay:5.0];

使用 GCD 完成相同的事情:

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0*NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(), ^(void){
[selfcake];
});

二、使用dispatch_once实现线程安全单一执行要求

线程安全单一执行典型例子是单例,GCD 的 dispatch_once 能够保证传入的 block 被线程安全地唯一执行:

+ (id)sharedInstance {
staticAdivseDemoController *sharedInstance =nil;
staticdispatch_once_t onceToken =@"token";
dispatch_once(&onceToken, ^{
sharedInstance = [[selfalloc] init];
});
returnsharedInstance;
}

这是现在 Objective-C 中实现单例较为推荐的一种方法。

在需要更细粒度控制线程时,考虑 NSOperation

GCD 虽然在很多地方值得提倡,但并不是任务管理和多线程地唯一解决方案,并不是说所有的地方都应该使用 GCD。GCD 是一个纯 C API,NSOperation 是 Objective-C 类,在一些地方对象编程是有优势的。NSOperation 也提供了一些 GCD 无法实现,或者 GCD 所没有的功能。

以下是你需要考虑使用 NSOperation 的一些理由:

当你需要取消线程任务时,GCD 无法提供取消任务的操作。而 NSOperation 提供了取消任务的操作;

当你需要更细的粒度地观察任务改变了状态时,由于 NSOperation 是一个对象,比较 GCD 使用的 block 而言,通过对NSOperation对象进行键值观察(KVO)能很容易观察到任务的状态改变;

当你需要重用线程任务时,NSOperation 作为一个普通的 Objective-C 对象,可以存储任何信息。对象就是为重用而设计的,这时,NSOperation 比 GCD 使用的 block 要更方便。

三、总结

OS X 和 iOS 系统提供了丰富的多线程工具。这些工具中,最新最现代的是 GCD(Grand Central Dispatch)。GCD 也是 Apple 公司推荐的多线程解决方案。所以,对于多线程技术的选择,总结下来有这两条建议:

  1. 能够使用 GCD 的地方,尽量使用 GCD;

  2. 在需要更细粒度控制线程时,考虑 NSOperation。

谢谢!!!

正文到此结束
Loading...