Swift4里的Operation和OperationQueue(上)

Operation概览:

Operation是一个抽象类,不能直接使用,需要继承Operation实现一个子类才能使用,但是系统已经帮我们实现了一个子类BlockOperation,NSInvocationOperation在Swift4里已经去掉了。尽管Operation是抽象类,但是他已经为我们实现了和系统对象的交互,我们只需要添加任务到对象就行,其他的都已经被Operation实现了,无需关心。

一个Operation对象只能执行一次,然后就废了。一般来说,我们需要把Operation添加到OperationQueue对象里,OperationQueue会自动取出Operation对象来执行,OperationQueue执行任务有两种方式,直接在线程上执行,或者调用GCD,一切都由系统来完成,无需关心。

如果你不想添加到OperationQueue里,可以调用Operation的start()方法来开启任务,直接开启任务会有额外的负担,因为执行未就绪的Operation可能会引起异常。Operation的就绪状态由只读属性isReady来标记。所以我们不会直接执行Operation,而是添加到OperationQueue里。

Operation的依赖关系:

依赖关系可以决定执行顺序,可以通过addDependency(:)和removeDependency(:) 来添加和删除依赖。被依赖的Operation先执行,比如op1依赖op2,op1在op2没有完成之前是不会执行的。一点op2执行完,op1就会进入就绪状态,并且可以执行。

op1并不关心op2是否已正确完成,当op2里发生错误,将op2标记为已完成,op1一样可以开始执行。这时候就需要手动追踪错误,来决定是否继续op1。

Operation符合KVO的属性:

Operation有几个属性可以进行KVO,如果需要,可以用KVO来监控:

  1. isCancelled
  2. isAsynchronous
  3. isExecuting
  4. isFinished
  5. isReady
  6. dependencies
  7. queuePriority
  8. completionBlock

虽然可以KVO,但是观察者不能用户界面类,比如UIView,因为UI界面必须在主线程中使用,Operation却可能在任何线程中执行。

如果你自定义一个Operation子类来实现上面的属性,必须让他们遵从KVC和KVO,如果添加了新的属性,最好也遵守KVC和KVO。

Multicore Considerations:

Operation本身是多线程安全的,不需要加锁来同步线程操作。如果你自定义子类,在子类里添加的方法必须要保证多线程安全。

同步和异步:

如果你不把Operation添加到OperationQueue里,而是手动开启操作,你可以指定操作是同步执行还是异步执行。默认情况下,操作是同步的。在同步操作中,操作对象不会创建一个单独的线程来运行它的任务。当您直接从代码调用同步操作的start()方法时,操作将立即在当前线程中执行。当该对象的start()方法将控制权返回给调用者时,任务本身就完成了。

当你调用异步操作的start()方法时,该方法可能在相应任务完成之前返回。异步操作对象负责将其任务安排在一个单独的线程上。该操作可以通过调用异步方法或将一个任务提交到GCD来执行,从而直接启动一个新线程。当控制权返回给调用者时,操作可能还在执行。

如果你用OperationQueue来执行Operation,想要同步很简单。但是如果手动操作Operation,想要异步却很麻烦。你需要用KVO来监听任务状态。所以不要直接使用Operation开启操作,用OperationQueue可以轻松控制Operation的同步和异步。

当把Operation添加到OperationQueue时,会忽略Operation的isAsynchronous的属性,并且总是开启新线程来调用Operation的start()方法。因此,isAsynchronous属性在此时就没用了。

子类化时的注意点:

Operation仅提供了跟踪操作状态的逻辑,具体执行代码的方式,需要子类来定义。怎么定义子类,取决于同步或者异步来执行任务:

需要重载的方法:

如果同步执行,只需要重载一个方法,就是:

  • main():在这个方法里执行你的任务。需要定一个初始化方法,以便容易初始化一个自定义类。可能还需要一个getter和setter方法来获取操作的数据,如果你实现了这两个方法,就要保证他们是多线程安全的。

如果你需要定义异步操作,还需要实现下面的方法和属性:

  • start()
  • isAsynchronous
  • isExecuting
  • isFinished

在并发操作中,start()方法负责以异步方式启动操作。无论是开启新线程,还是调用异步函数,都是在这个方法里执行的。启动操作后,start()方法还要更新isExecuting属性。可以通过KVO来通知观察者isExecuting的改变。isExecuting属性必须要线程安全。

在完成它的任务或取消,你的并发操作对象必须生成KVO通知双方执行和完成关键路径为您的运行状态的最终变化标志。(在取消的情况下还是更新是关键路径,重要的即使操作没有完全完成它的任务。队列操作必须报告,他们才可以从队列中移除了。)除了生成KVO通知,你的执行和完成的覆盖性能也应该继续报告准确的值取决于你的工作状态。

在完成任务或者取消任务时,你的并发operation对象会生成isExecuting和isFinished的KVO通知,来标记operation的最终状态。(在取消的情况下,即使任务没有完成,更新isFinished状态也是必要的。在queue里排队的operation必须在从queue里移除之前报告isFinished的状态)除了生成KVO通知,覆盖的isExecuting和isFinished属性也应该准确的记录operation的状态的准确值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容