Farlanki

NSOperation和NSOperationQueue

字数统计: 605阅读时长: 2 min
2015/12/06 Share

简介

NSOperationNSOperationQueueGCD的封装.NSOperation和NSOperationQueue对应的分别是GCD中的任务和队列.

特性

对比GCD,NSOperation提供了一些新的特性,例如取消队列中的任务,这在一些场景下将会大大减少cpu的运算量.试想一下你要实现一个下载大量图片并在UICollectionView中展示的应用,一般情况下是当用户滑动UICollectionView到达了一定地方的时候,新的图片将会被下载以填充即将要展示的view.那么当用户快速滑过UIConnectionView的时候,很多view已经被滑出屏幕但是加载当中的图片的任务已经被加到队列中了,在GCD的情况下这些任务将不能被取消,而使用NSOperation将不会出现这个情况.

添加任务

NSOperation是一个抽象基类,它的两个子类NSBlockOperationNSInvocationOperation用于封装任务.创建一个任务后如果不把它加入NSOperationQueue中,可以直接使用start()方法,那么这个任务将在主线程运行.

addExecutionBlock:

使用addExecutionBlock:方法可以在一个Operation中添加多个block.这样start()的任务会在主线程和其他的多个线程中并发执行.

自定义任务

可以自己实现NSOperation的子类,重写其中的main或者start方法来自定义任务.

创建队列

队列分为主队列和其他队列,使用其他队列时任务会在其他线程并行执行.

1
2
3
4
5
let mainQueue = NSOperationQueue.mainQueue()
//创建一个主队列

let queue = NSOperationQueue()
//创建一个其他队列

maxConcurrentOperationCount

maxConcurrentOperationCount是创建队列时指定的一个参数,指的是一个队列的最大并发数,如果一个队列的最大并发数设置为1,那么这个队列就是串行队列了.

依赖

依赖是NSOperation中一个十分使用的功能

1
operationA.addDependency(operationB)

指的是在若operationA的执行需要以operationB的完成作为条件.
通过依赖,可以实行类似GCD上的dispatch_group的功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var operationArray = [NSOperation]()
for i in 0..<10
{
var operation = NSBlockOperation(block: { () -> Void in
sleep(arc4random_uniform(3))
print(i)
})
operationArray.append(operation)
}

var finishOperation = NSBlockOperation { () -> Void in
print("finish")
}

for operation in operationArray{
finishOperation.addDependency((operation as! NSOperation))
}

operationArray.append(finishOperation)

var operationQueue = NSOperationQueue()
operationQueue.addOperations(operationArray, waitUntilFinished: false)

输出:
0
3
8
2
1
4
5
6
7
9
finish

其他

下面列出了几个常用的功能

1
2
3
operationA.cancel()//取消任务
queueA.setSuspended(true)//暂停队列
queueA.setSuspended(false)//继续队列
CATALOG
  1. 1. 简介
  2. 2. 特性
  3. 3. 添加任务
    1. 3.1. addExecutionBlock:
  4. 4. 自定义任务
  5. 5. 创建队列
    1. 5.1. maxConcurrentOperationCount
  6. 6. 依赖
  7. 7. 其他