原创blog,转载请注明出处
blog.youkuaiyun.com/hello_hwc
欢迎关注我的iOS SDK详解专栏,这里有很多基础的文章
http://blog.youkuaiyun.com/column/details/huangwenchen-ios-sdk.html
前言:在iOS开发 中,多线程是一个很重要的一个方面。iOS的多线程使用可以分为几个方面。由底层到上层分别是
- pthread
- NSThread
- GCD
- NSOperationQueue
这里不得不提到一点,操作系统是以线程为任务调度基本单位,对于一个单核CPU,实际上是采用时间片轮转来实现多线程的。而对于多核CPU,则可以实现真正的并发执行。
我的iOS SDK讲解系列并不会详细讲解pthread 和 NSThread,二者很少会用到,也很容易在使用时候出问题。
本文会简单讲解下NSOperationQueue以及NSOperation,并且给出一个简单的Demo实现串行和并行的NSOperation
简单介绍下pthread和NSThread
pthread 是Unix层次的线程,相当底层。可以参见WIKI。
NSThread是对pthread的进一步封装,但是仍然在使用的时候出现各种各样的问题。
在iOS开发的过程中,有一点要谨记:
尽可能的使用上层API去实现,除非上层API没办法实现再考虑底层API
NSOperationQueue概述
NSOperationQueue把线程操作抽象成队列操作,它是GCD的上层封装,队列中是一个个的NSOperation,NSOperation用来定义任务的具体执行。
使用NSOperationQueue和NSOperation相关的API可以方便而安全的的进行
- 取消一个任务
- 添加任务的依赖关系,例如任务3要再任务1和任务2执行完毕才能执行
- 设置一个Queue最多同时执行的任务数量。默认情况Queue会做到最优化执行。
- KVO监听任务的状态变化
另外,NSOperationQueue也分为两种
- mainQueue(主线程),注意只能在主线程处理UI相关。
- 自定义Queue(后台线程)。
当把一个NSOperation添加到自定义Queue后,会在当前线程之外的另一个线程来执行操作。
NSOperation 概述
写了个简单的Demo,异步下载3张图片。
- 为下载提供独立的进度条
- 每次队列只允许一个下载任务进行
NSOperation用来封装要实现的任务,注意这些任务是一次性的,不能重复利用。通常执行任务要把Operation添加到OperationQueue。等到任务执行完毕后,Operation会被从Queue上移除并且销毁。
有几点要提到:
- NSOperation是一个抽象类,使用的时候要使用它的子类来定义任务
- NSOperation是线程安全的,也就是说在不同线程上访问NSOperation对象是安全的。同样,为NSOperation子类添加的方法也要是线程安全的。
- NSOperation分为两种,一种是同步的,一种是异步的。这个接下来会详细讲解
- NSOperation的很多属性支持KVO
支持KVO的属性
isCancelled - read-only
isAsynchronous - read-only
isExecuting - read-only
isFinished - read-only
isReady - read-only
dependencies - read-only
queuePriority - readable and writable
completionBlock - readable and writable
同步的NSOperation
注意,这里的同步异步是相对任务本身的,同步的任务指的是start-main-结束,main结束后,则任务结束。异步的任务例如有网络请求的,main函数结束了,任务还没结束。
注意:
- init和start函数都是在创建NSOperation线程上执行的。
- main是在后台线程上执行的。
对于同步的NSOperation来说,只需要重写main函数,保证main函数里的任务是同步执行的。
例如用NSOperationQueue下载一副图片。
头文件
我们传入imageview,