34. 多线程之NSOperation和NSOperationQueue

NSOperation

NSOperation是GCD面向对象的封装, 它有更多的特性.

文档中说NSOperation是一个抽象类, 不要直接使用它,使用它的子类或定义一个继承它的类.它的子类有 NSInvocationOperation 和NSBlockOperation, 貌似swift中没有NSInvocationOperation类, 我们就只管NSBlockOperation了.

1. NSBlockOperation和NSOperationQueue的使用

import UIKit

class ViewController: UIViewController {

    var queue: NSOperationQueue!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.queue = NSOperationQueue()
        // 设置线程池最大线程数
        queue.maxConcurrentOperationCount = 5
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func startAction(sender: AnyObject) {

        let downloadOP = NSBlockOperation { () -> Void in
            print("下载小说, \(NSThread.currentThread())")
        }

        let analysisOP = NSBlockOperation { () -> Void in
            print("分析目录结构, \(NSThread.currentThread())")
        }

        let sortOP = NSBlockOperation { () -> Void in
            print("章节排序, \(NSThread.currentThread())")

            // 主线程上更新UI
            NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                print("显示小说, \(NSThread.currentThread())")
            })
        }

        // analysisOP依赖downloadOP,即下载完成后才分析目录结构
        analysisOP.addDependency(downloadOP)
        sortOP.addDependency(analysisOP)

        self.queue.addOperation(downloadOP)
        self.queue.addOperation(analysisOP)
        self.queue.addOperation(sortOP)
    }
}

这里我们创建一个NSOperationQueue, 看名字就知道是一个队列了, 我们简单的把它当一个线程池就行了,maxConcurrentOperationCount可以设置它的线程池中的最大线程数目.

NSBlockOperation实例后要添加到queue中才会执行.我们可以通过addDependency设置不同NSBlockOperation之间的依赖关系,以便控制线程的执行顺序. 更新UI的操作要放到主队列中–NSOperationQueue.mainQueue().

运行程序,我们点击按钮:

下载小说, <NSThread: 0x7f8383db13c0>{number = 2, name = (null)}
分析目录结构, <NSThread: 0x7f8383db13c0>{number = 2, name = (null)}
章节排序, <NSThread: 0x7f8383db13c0>{number = 2, name = (null)}
显示小说, <NSThread: 0x7f8383d04a80>{number = 1, name = main}

通过线程的number我们可以知道 下载小说, 分析目录结构, 章节排序实在新开的线程中运行的, 而显示小说是在主线程中运行的.

2. NSOperationQueue的定义

我们查看NSOperationQueue的定义:

@available(iOS 2.0, *)
public class NSOperationQueue : NSObject {
    // 添加NSOperation
    public func addOperation(op: NSOperation)
    @available(iOS 4.0, *)
    public func addOperations(ops: [NSOperation], waitUntilFinished wait: Bool)


    @available(iOS 4.0, *)
    public func addOperationWithBlock(block: () -> Void)

    // 获取所有NSOperation
    public var operations: [NSOperation] { get }
    // 获取NSOperation的数目
    @available(iOS 4.0, *)
    public var operationCount: Int { get }

    // 最大并发线程数
    public var maxConcurrentOperationCount: Int

    // 是否挂起(暂停)
    public var suspended: Bool

    // NSOperationQueue的名字
    @available(iOS 4.0, *)
    public var name: String?

    // 服务质量, 级别越高,获得的资源越多
    @available(iOS 8.0, *)
    public var qualityOfService: NSQualityOfService

    @available(iOS 8.0, *)
    unowned(unsafe) public var underlyingQueue: dispatch_queue_t? /* actually retain */

    // 取消queue的所有操作
    public func cancelAllOperations()

    // 阻塞当前线程,等待queue的所有操作执行完毕, 所以不要在主线程中调用  
    public func waitUntilAllOperationsAreFinished()

    // 获取当前队列
    @available(iOS 4.0, *)
    public class func currentQueue() -> NSOperationQueue?
    // 获取主队列
    @available(iOS 4.0, *)
    public class func mainQueue() -> NSOperationQueue
}

3. NSOperation的定义

我们查看NSOperation的定义:

@available(iOS 2.0, *)
public class NSOperation : NSObject {
    // 开始任务
    public func start()
    public func main()

    // 操作是否取消
    public var cancelled: Bool { get }
    // 取消任务
    public func cancel()

    // 任务是否正在执行
    public var executing: Bool { get }
    // 任务是否执行完成
    public var finished: Bool { get }
    // 是否并发,已经过时了, 使用下面的asynchronous
    public var concurrent: Bool { get } 
    @available(iOS 7.0, *)
    public var asynchronous: Bool { get }
    // 是否已经准备好
    public var ready: Bool { get }

    // 添加删除依赖
    public func addDependency(op: NSOperation)
    public func removeDependency(op: NSOperation)

    // 获得所有的依赖NSOperation
    public var dependencies: [NSOperation] { get }

    // 队列优先级
    public var queuePriority: NSOperationQueuePriority

    // 完成回调
    @available(iOS 4.0, *)
    public var completionBlock: (() -> Void)?

    // 等待完成
    @available(iOS 4.0, *)
    public func waitUntilFinished()

    // 线程优先级
    @available(iOS, introduced=4.0, deprecated=8.0)
    public var threadPriority: Double

    // 服务质量
    @available(iOS 8.0, *)
    public var qualityOfService: NSQualityOfService

    // 名字
    @available(iOS 8.0, *)
    public var name: String?
}

4. 完整代码

同第一部分

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值