IOS多线程-NSOperation

By | 2015年5月22日

NSOperation是苹果为我们封装自GCD的一个类,操作方法很简便,适合对复杂的多线程进行操作,少量的多线程使用,还是用GCD速度快。

//使用系统提供的继承于NSOperation的子类
let operation = NSBlockOperation{
    //需要执行的操作,比如从网络下载图片
}
//将Operation添加到队列中
NSOperationQueue().addOperation(operation)

NSOperation队列完成后,可以使用completionBlock来定义回调方法:

//添加完成后的回调
operation.completionBlock = {
    println("Finish")
}

可以自定义NSOperation,继承NSOperation类,实现main方法:

import UIKit


protocol OperationDelegate{
    func completion(data:NSData)
}

class MyOperation: NSOperation {

    var delegate:OperationDelegate?

    override func main() {
        super.main()

        let data1 = NSData(contentsOfURL: NSURL(string: "http://cdn.duitang.com/uploads/item/201206/25/20120625200704_NreVX.thumb.600_0.jpeg")!)

        if(data1 != nil){

            dispatch_async(dispatch_get_main_queue()){
                if let myDelegate = self.delegate{
                    myDelegate.completion(data1!)
                }
            }

        }//end if
    }//end main
}

MyOperation类继承了NSOperation,重写了main方法,先下载一张图片,然后使用协议委托的方式将图片数据传给completion方法,由这个方法来对图片进行现实处理,由于是需要更新UI,把它放在了main_queue中。

下面是实现ViewController中的实现:

class ViewController: UIViewController,OperationDelegate {

@IBAction func btnClick(sender: AnyObject) {
  //使用自定义Operation
  let operation = MyOperation()
  operation.delegate = self
  NSOperationQueue().addOperation(operation)
}
//实现completion方法
func completion(data: NSData) {
    self.imgView.image = UIImage(data: data)
}
}

我们可以设置多个Operation之间的依赖性,如果操作1依赖操作2,那么操作2会先执行,完成后才运行操作1:

//设置依赖性,operation1依赖Operation2,所以Operation2先执行,完成后,再执行operation1
let operation1 = MyOperation()
let operation2 = MyOperation()
operation1.addDependency(operation2)

可以设置Operation的优先级,为系统调度提供一个权重,不会因为操作1的优先级高于操作2,操作2就先执行:

//虽然operation1的优先级高于Operation2,但不一定Operation1先执行,谁先执行是由系统决定的
operation1.queuePriority = NSOperationQueuePriority.VeryHigh
operation2.queuePriority = NSOperationQueuePriority.VeryLow

在NSOperatoinQueue中,我们可以设置队列的并发数:

//并发数为1,相当于串行执行了,同时只能一个operation执行
let queue = NSOperationQueue()
queue.maxConcurrentOperationCount = 1