yellowChao


一位漂泊在北京的重庆崽儿,iOS、Node.js 开发者


我的Swift学习之路(八)--多线程编程(二)

NSOperation 核心概念

在iOS开发中,为了提升用户体验,我们通常会将操作耗时的操作放在主线程之外的线程进行处理。对于正常的简单操作,我们更多的是选择代码更少的GCD,让我们专注于自己的业务逻辑开发。NSOperation在ios4后也基于GCD实现,但是相对于GCD来说可控性更强,并且可以加入操作依赖。NSOperation是对GCD面向对象的ObjC封装,建议如果任务之间有依赖关系或者想要监听任务完成状态的情况下优先选择NSOperation否则使用GCD。

  • NSOperationNSInvocationOperation 在Swift中已经被禁止使用了,取而代之的是使用NSBlockOperation (NSOperation的子类)
  • NSOperationQueue 负责管理、执行所有的NSOperation

基本演练

NSBlockOperation 简单的直接添加 Block

let operation = NSBlockOperation {
print(NSThread.currentThread())
}

let operationQueue = NSOperationQueue()
operationQueue.addOperation(operation)

使用 block 来定义操作,所有的代码写在一起,更简单,便于维护!

线程间通讯

let queue = NSOperationQueue()
queue.addOperationWithBlock {
print("do something in \(NSThread.currentThread())")
NSOperationQueue.mainQueue().addOperationWithBlock {
print("update UI element in \(NSThread.currentThread())")
}
}

高级演练

let queue = NSOperationQueue()
queue.maxConcurrentOperationCount = 5 //设置最大并发数
queue.suspended = false // 设置队列是否挂载;false为继续, true为暂停
queue.cancelAllOperations()//取消对列中的所有操作,同样不会影响到正在执行中的操作
  • 队列挂起,当前”没有完成的操作”,是包含在队列的操作数中的
  • 队列挂起,不会影响已经执行操作的执行状态
  • 对列一旦被挂起,再添加的操作不会被调度

  • 取消队列中所有的操作

  • 不会取消正在执行中的操作
  • 不会影响队列的挂起状态

依赖关系

let loginAction = NSBlockOperation { 
print("登录操作 in\(NSThread.currentThread())")
}
let payAction = NSBlockOperation {
print("付费操作 in\(NSThread.currentThread())")
}
let downloadAction = NSBlockOperation {
print("下载操作 in\(NSThread.currentThread())")
}
let notifacationAction = NSBlockOperation {
print("通知用户 in\(NSThread.currentThread())")
}

payAction.addDependency(loginAction)
downloadAction.addDependency(payAction)
notifacationAction.addDependency(downloadAction)
// 注意不要循环依赖

let queue = NSOperationQueue()
queue.maxConcurrentOperationCount = 1
queue.addOperations([loginAction, payAction, downloadAction], waitUntilFinished: false)
NSOperationQueue.mainQueue().addOperation(notifacationAction)

与 GCD 的对比

  • GCD

    • 任务(block)添加到队列(串行/并发/主队列),并且指定任务执行的函数(同步/异步)
    • GCD是底层的C语言构成的API
    • iOS 4.0 推出的,针对多核处理器的并发技术
    • 在队列中执行的是由 block 构成的任务,这是一个轻量级的数据结构
    • 要停止已经加入 queueblock 需要写复杂的代码
    • 需要通过 Barrier 或者同步任务设置任务之间的依赖关系
    • 只能设置队列的优先级
    • 高级功能:
      • 一次性 once
      • 延迟操作 after
      • 调度组
  • NSOperation

    • 核心概念:把操作(异步)添加到队列(全局的并发队列)
    • OC 框架,更加面向对象,是对 GCD 的封装
    • iOS 2.0 推出的,苹果推出 GCD 之后,对 NSOperation 的底层全部重写
    • Operation作为一个对象,为我们提供了更多的选择
    • 可以随时取消已经设定要准备执行的任务,已经执行的除外
    • 可以跨队列设置操作的依赖关系
    • 可以设置队列中每一个操作的优先级
    • 高级功能:
      • 最大操作并发数(GCD不好做)
      • 继续/暂停/全部取消
      • 跨队列设置操作的依赖关系