前言
Operation
同步Operation使用教程
重写main()方法即可。
异步Operation使用教程
参考该Blog即可。
Asynchronous operations for writing concurrent solutions in Swift
总结:重写
- isExecuting
- isFinished
- isAsynchronous
- start()
重写这些属性,是为了手动控制异步Operation的生命周期。而不是跑完main函数,op就finish了。
finish属性直接影响依赖它的Op。
B依赖A,A的finish属性KVO信号触发B开始运行。
Operations之间的依赖如何实现
B.addDependency(A)。
1.添加
把A添加进B依赖的数组。
2.A执行完毕
等A执行完毕,finish = YES,回去遍历一个数组,数组中存放所以依赖自己的Op。 该Op如果只是依赖A,那会立刻开始执行自己的start函数。 该Op如果如果还依赖其他Op,那只是依赖count-1。
barrier Operation
barrier Operation 调用时机的实现
往queue里面添加10个Op,再添加barrier Operation。如何保证bOp在10个Op后执行?
barrier Operation依赖10个Op.10个Op都执行完毕,自然会执行barrier Operation。
barrier Operation 是如何实现阻拦其他Operation的
所有添加到queue里面的Op都会依赖一个数组。 barrier Operation数组,你添加一个bOp,就相当于往bOp list里添加bOp。 Op的执行,必然在依赖的所有bOp执行完毕后执行。
约等于oP.addDependency([barrier Operation list])。
OperationQueue
Operations的优先级调度如何实现
OperationQueue里有6个优先级链表,外加一个总链表。
每个Operations被添加到OperationQueue里时,都会因为优先级被分配到不同链表中。
每次执行时,遍历高优先级到低优先级的链表,所以高优先级op会被优先执行。
Operation修改优先级会发生
changePriority。
- 从原来的优先链表中移除。
- 添加到新优先链表的最后面。
OperationQueue如何实现并发量的控制
OperationQueue每执行一个op,计数+1。一个op finish,计数-1。
如果max = 8,当前计数 = 8.将不在去派发Op。计数小于max,派发Op。
OperationQueue,Operation用了哪些GCD的API
DispatchWorkItem:Operation的start都会被封装进WorkItem
DispatchQueue:用于派发任务,异步调用WorkItem.perform()。
waitUntilFinished 的使用和实现
waitUntilFinished = true,NSCondition堵住当前线程。
直到Op finish时,NSCondition 广播,被堵住的op才能继续执行。
OperationQueue 的内部任务派发机制(big problem)
进阶
从Operation添加到被执行,中间发生了什么
添加到队列
- Operation依据Qos被封装成DispatchWorkItem,作为自己的属性,方便到时候的派发。
- Operation依据Qos等级,被分配到对应优先级的链表。
执行
- OperationQueue 并发分配任务,从优先级高的链表开始调度。
- 没有超过最大并发数,异步执行被封装的DispatchWorkItem。
高阶Operation用法
解决地狱回调
通常的网络请求
1.网络请求
2.请求回调中,解析json,转成model
3.最后调用complete函数
这是最常见的。如果业务更复杂,可能存在非常多的回调嵌套。简称地狱回调。
高阶用法,完美解决过层嵌套,回调嵌套问题。⚠️:每个OP里面需要处理错误。如果网络请求OP返回错误。立刻结束解析。complete OP 也需要处理解释失败。总的来说,解决了地狱回调。
1.网络请求OP
2.解析json,转成model OP
3.最后调用complete函数 OP
2依赖1
3依赖2
这3个OP可以运行在一个OperationQueue中。
解决网络延迟
- 比如你有一个业务,进入页面A,发起网络请求去获取一些数据(定义为OP Network)。
- 但A的页面的展示内容是存在本地的,已经加载完毕,并且渲染完毕。是一个tableview。
- 你点击cell 1 (定义为OP click)。此刻网络请求还没有返回,你该怎么办?
这个时候,就可以用OP。 依赖:OP click依赖于OP Network。等OP Network请求回来后,自然会触发OP click。
如果你不用op,这时候点击就很难处理,你必须存起来。等请求回来,看看有没有待完成业务。OperationQueue 帮你实现了操作前提,而且存储了操作。优秀!
Operation UI
把UI操作封装成Operation有没有必要?绝大部分业务都没有必要。
什么情况下用Operation UI。该UI操作依赖某些数据,暂时还没获取到。
Operation UI 依赖 Operation asynData Get这种情况把UI操作封装成Op。 如上一个例子