NSOperation介绍:
NSOperation是基于GCD实现,封装了一些更为简单实用的功能,因为GCD的线程生命周期是自动管理,所以NSOperation也是自动管理。NSOperation配合NSOperationQueue也可以实现多线程。
实现步骤
第1步:将一个操作封装到NSOperation对象中
第2步:将NSOperation对象放入NSOperationQueue队列
第3步:NSOperationQueue自动取出队列中的NSOperation对象放到一条线程中执行
具体实现
在swift中的实现方式分2种(oc还多了一个NSInvocationOperation,并且在oc中NSOperation是个抽象类):
1.NSBlockOperation
2.自定义子类继承NSOperation
1.NSOoperation常用操作,创建队列,设置最大并发数。
//创建队列
let queue = NSOperationQueue()
//设置最大并发数
queue.maxConcurrentOperationCount=2
//创建operation
let operation = NSBlockOperation { () -> Void in
print("doSomething1 \(NSThread.currentThread())")
}
//当operation有多个任务的时候会自动分配多个线程并发执行,
//如果只有一个任务,会自动在主线程同步执行
//operation.start()
operation.addExecutionBlock { () -> Void in
print("doSomething2 \(NSThread.currentThread())")
}
operation.addExecutionBlock { () -> Void in
print("doSomething3 \(NSThread.currentThread())")
}
let operation2=NSBlockOperation { () -> Void in
print("doSomething4 \(NSThread.currentThread())")
}
//添加到队列中的operation将自动异步执行
queue.addOperation(operation)
queue.addOperation(operation2)
//还有一种方式,直接将operation的blcok直接加入到队列
queue.addOperationWithBlock { () -> Void in
print("doSomething5 block \(NSThread.currentThread())")
}
queue.addOperationWithBlock { () -> Void in
print("doSomething6 block \(NSThread.currentThread())")
}
queue.addOperationWithBlock { () -> Void in
print("doSomething7 block \(NSThread.currentThread())")
}
queue.addOperationWithBlock { () -> Void in
print("doSomething8 block \(NSThread.currentThread())")
}
2.NSOperation操作依赖,可设置一个操作在另一个操作完成后在执行
//创建队列
let queue = NSOperationQueue()
let operationA = NSBlockOperation { () -> Void in
print("print A")
}
let operationB = NSBlockOperation { () -> Void in
print("print B")
}
let operationC = NSBlockOperation { () -> Void in
print("print C")
}
//B等A执行完才执行
operationB.addDependency(operationA)
//C等B执行完才执行
operationC.addDependency(operationB)
queue.addOperation(operationA)
queue.addOperation(operationB)
queue.addOperation(operationC)
3.NSOperation操作监听,一个操作完成后调用另一个操作:
func operationCompletion(){
//创建队列
let queue = NSOperationQueue()
let operation = NSBlockOperation { () -> Void in
print("print A")
}
operation.completionBlock = doSomething
queue.addOperation(operation)
}
func doSomething(){
print("doSomething")
}
4.NSOperation线程通信,NSOperationQueue.mainQueue。
//创建队列
let queue = NSOperationQueue()
queue.addOperationWithBlock { () -> Void in
print("子线程 \(NSThread.currentThread())")
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
print("主线程 \(NSThread.currentThread())")
})
}
注意:
1.在使用队列任务的时候,内存警告的时候可使用队列的cancelAllOperations函数取消所有操作,注意一旦取消不可恢复。亦可设置队列的suspended属性暂停和恢复队列。
2.在设置操作依赖的时候不能设置循环依赖。
NSOperation和GCD区别:
关于GCD的介绍参考:http://blog.csdn.net/watertekhqx/article/details/61920925
NSOpertaionQueue
用GCD构建封装的,是GCD的高级抽象。
1>GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本的封装
2>GCD只支持FIFO的队列,NSOperationQueue可以很方便的调整执行顺序,并且设置线程最大的并发数量
3> NSOperationQueue可可以轻松的在Operation之间设置依赖关系,而GCD需要写很多的代码才能实现
4> NSOperationQueue支持KVO,可以监听Operation是否正在执行(isExecuted),是否结束(isFinished),是否取消(isCanceled)
5>GCD的执行速度比NSOperationQueue快
6>人物之间的依赖性不强,用GCD,人物之间的有依赖/或者要监听任务的执行情况,用NSOperationQueue
详解区别:GCD仅仅支持FIFO队列,而NSOperationQueue中的队列可以被重新设置优先级,从而实现不同操作的执行顺序调整。
GCD不支持异步操作之间的依赖关系设置。如果某个操作的依赖另一个操作的数据(生产者-消费者模型是其中之一),使用NSOperationQueue能够按照正确的顺序执行操作。GCD则没有内建的依赖关系支持。
NSOperationQueue支持KVO,意味着我们可以观察任务的执行状态。
从以下角度来定义原则:
1. 性能
GCD更接近底层,而NSOperationQueue则更高级抽象,所以GCD在追求性能的底层操作来说,是速度最快的。这取决于使用Instruments进行代码性能分析,如有必要的话
2. 从异步操作之间的事务性,顺序行,依赖关系。GCD需要自己写更多的代码来实现,而NSOperationQueue已经内建了这些支持
3. 如果异步操作的过程需要更多的被交互和UI呈现出来,NSOperationQueue会是一个更好的选择。底层代码中,任务之间不太互相依赖,而需要更高的并发能力,GCD则更有优势