NSThread、NSOperation、GCD 总结:
无论使用哪种方法进行多线程开发,每个线程启动后并不一定立即执行相应的操作,具体什么时候由系统调度(CPU 空闲时就会执行)
更新 UI 应该在主线程(UI 线程)中进行,并且推荐使用异步调用,避免造成线程阻塞,常用的方法如下:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL) wait; //方法传递主线程[NSThread mainThread])
[NSOperationQueue mainQueue] addOperationWithBlock:
dispatch_async(dispatch_get_main_queue(), ^{}) //在主线程中,这里改用同步调用 dispatch_sync 的话就会造成线程阻塞情况
NSThread 适合轻量级多线程开发,控制线程顺序比较难,同时线程总数无法控制(每次创建并不能重用之前的线程,只能创建一个新的线程)
对于简单的多线程开发建议使用 NSObject 的扩展方法完成,而不必使用 NSThread
可以使用 NSThread 的 currentThread 方法取得当前线程,使用 sleepForTimeInterval: 方法让当前线程挂起
NSOperation 进行多线程开发可以控制线程总数及线程依赖关系
创建一个 NSOperation 不应该直接调用 start 方法(如果直接 start 则会在主线程中调用)而是应该放到 NSOperationQueue 中启动
相比 NSInvocationOperation 推荐使用 NSBlockOperation,代码简单,同时由于闭包性使他没有传参问题
NSOperation 是对 GCD 面向对象的 OC 封装。而 GCD 基于 C 语言开发,效率更高。建议如果任务之间有依赖关系或者想要监听任务完成状态的情况下优先选择 NSOperation,否则使用 GCD。
NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且线程安全的建立状态,优先级,线程数目,依赖和取消等操作
在 GCD 中串行队列中的任务被安排到一个单一线程执行(不是主线程),可以方便地控制执行顺序;并发队列在多个线程中执行(前提是使用异步方法),顺序控制相对复杂,但是更高效
在 GCD 中一个操作是多线程还是单线程执行,取决于当前队列类型和执行方法。只有队列类型为并行队列并且使用异步方法执行时才能在多个线程中执行(如果是并行队列使用同步方法调用则会在主线程中执行)