注册
iOS

swift 多线程下

Swift多线程编程方案:



  • Thread

  • Cocoa Operation (OperationOperationQueue)

  • Grand Central Dispath (GCD)



1. Thread在三种多线程技术中是最轻量级的, 但需要自己管理线程的生命周期和线程同步. 线程同步对数据的加锁会有一定的系统开销.



  • detachNewThread(_ block: @escaping () -> Void)
  • detachNewThreadSelector(_ selector: Selector, to Target target: Any, with argument: Any?)


e.g.

for i in 0...10 {
Thread.detachNewThread {
print("\(i) \(Thread.current)")
}
}

输出结果:

8 <NSThread: 0x6000000f8e40>{number = 12, name = (null)}
10 <NSThread: 0x6000000f0240>{number = 17, name = (null)}
7 <NSThread: 0x6000000cc0c0>{number = 10, name = (null)}
1 <NSThread: 0x6000000c0180>{number = 14, name = (null)}
6 <NSThread: 0x6000000efe80>{number = 9, name = (null)}
4 <NSThread: 0x6000000efdc0>{number = 11, name = (null)}
5 <NSThread: 0x6000000c8580>{number = 15, name = (null)}
9 <NSThread: 0x6000000cc080>{number = 8, name = (null)}
0 <NSThread: 0x6000000fd300>{number = 7, name = (null)}
2 <NSThread: 0x6000000cc5c0>{number = 13, name = (null)}
3 <NSThread: 0x6000000f0780>{number = 16, name = (null)}


e.g.

class ObjectForThread {
func threadTest() -> Void {
let thread = Thread(target: self, selector: #selector(threadWorker), object: nil)
thread.start()
print("threadTest")
}
@objc func threadWorker() -> Void {
print("threadWorker Run")
}
}

let obj = ObjectForThread()
obj.threadTest()

输出结果:

threadTest
threadWorker Run




2. OperationOperationQueue


Operation



  • 面向对象 (OperationBlockOperation)

  • Operation+ OperationQueue

  • 取消、依赖、任务优先级、复杂逻辑、保存业务状态、子类化

Operation的四种状态 :



  • isReady
  • isExecuting
  • isFinished
  • isCancelled

OperationQueue




  • OperationQueue队列里可以加入很多个Operation, 可以把OperationQueue看做一个线程池, 可以往线程池中添加操作(Operation)到队列中
  • 底层使用GCD


  • maxConcurrentOperationCount可以设置最大并发数

  • defaultMaxConcurrentOperationCount根据当前系统条件动态确定的最大并发数
  • 可以取消所有Operation, 但是当前正在执行的不会取消
  • 所有Operation执行完毕后退出销毁


e.g. BlockOperation

class ObjectForThread {
func threadTest() -> Void {
let operation = BlockOperation { [weak self] in
self?.threadWorker()
}
let queue = OperationQueue()
queue.addOperation(operation)
print("threadTest")
}
}

let obj = ObjectForThread()
obj.threadTest()


e.g. 自定义的Operation

class ObjectForThread {
func threadTest() -> Void {
let operation = MyOperation()
operation.completionBlock = {() -> Void in
print("完成回调")
}
let queue = OperationQueue()
queue.addOperation(operation)
print("threadTest")
}
}
class MyOperation: Operation {
override func main() {
sleep(1)
print("MyOperation")
}
}

let obj = ObjectForThread()
obj.threadTest()



3. GCD


GCD特点



  • 任务+队列
  • 易用
  • 效率
  • 性能

GCD - 队列



  • 主队列: 任务在主线程执行
  • 并行队列: 任务会以先进先出的顺序入列和出列, 但是因为多个任务可以并行执行, 所以完成顺序是不一定的.
  • 串行队列: 任务会以先进先出的顺序入列和出列, 但是同一时刻只会执行一个任务

GCD - 队列API



  • Dispatch.main
  • Dispatch.global
  • DispatchQueue(label:,qos:,attributes:,autoreleaseFrequency:,target:)
  • queue.label
  • setTarget(queue:DispatchQueue)


  • 最终的目标队列都是主队列和全局队列
  • 如果把一个并行队列的目标队列都设置为同一个串行队列, 那么这多个队列连同目标队列里的任务都将串行执行
  • 如果设置目标队列成环了, 结果是不可预期的
  • 如果在一个队列正在执行任务的时候更换目标队列, 结果也是不可预期的


e.g.

let queue = DispatchQueue(label: "myQueue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
queue.async {
sleep(3)
print("queue")
}
print("end")


e.g.

let queue = DispatchQueue(label: "myQueue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
queue.asyncAfter(deadline: DispatchTime.now() + 10) {
print("in asyncAfter")
}
print("end")

DispatchTime 系统时钟

DispatchWallTime生活时间


GCD 高级特性- DispatchGroup



e.g. 阻塞当前线程

let group = DispatchGroup()
let queue = DispatchQueue(label: "test.queue")

group.enter()
queue.async {
sleep(3)
print("操作 1")
group.leave()
}

group.enter()
queue.async {
sleep(3)
print("操作 2")
group.leave()
}

print("操作1 操作2 安排完成")

group.wait()
print("操作1 操作2 全部执行完毕")


e.g. 非阻塞方式:

let group = DispatchGroup()
let queue = DispatchQueue(label: "test.queue")

group.enter()
queue.async {
sleep(3)
print("操作 1")
group.leave()
}

group.enter()
queue.async {
sleep(3)
print("操作 2")
group.leave()
}

print("操作1 操作2 安排完成")

group.notify(queue: queue) {
print("操作1 操作2 全部执行完毕")
}
print("非阻塞")

GCD 高级特性- DispatchSource



  • 简单来说, dispatch source是一个监听某些类型事件的对象. 当这些事件方法时, 它自动将一个task放入一个dispatch queue的执行历程中.


e.g. DispatchSource- Timer

var seconds = 10
let timer: DispatchSourceTimer = DispatchSource.makeTimerSource(flags: .strict, queue: .global())
timer.schedule(deadline: .now(), repeating: 1.0)
timer.setEventHandler {
seconds -= 1
if seconds < 0 {
timer.cancel()
}
else {
print(seconds)
}
}
timer.resume()


链接:https://www.jianshu.com/p/b52728779891

0 个评论

要回复文章请先登录注册