Operation 十问-快问快答版

620 阅读4分钟

前言

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。

  1. 从原来的优先链表中移除。
  2. 添加到新优先链表的最后面。

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中。

解决网络延迟

  1. 比如你有一个业务,进入页面A,发起网络请求去获取一些数据(定义为OP Network)。
  2. 但A的页面的展示内容是存在本地的,已经加载完毕,并且渲染完毕。是一个tableview。
  3. 你点击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。 如上一个例子

Blog

异步Operations的使用

WWDC

Advanced NSOperations

wwdc2015 226源码

源码版本

Operation源码版本 2020_Feb_16