

ãããã¯ãŒã¯ããã®ããŒã¿ã®ããŠã³ããŒããç»ååŠçãªã©ã®æéã®ãããã³ãŒããå®è¡ããŠ
iOSã¢ããªã±ãŒã·ã§ã³ã®
UIå¿çæ§ãå®çŸããå Žåã¯ããã«ãã¹ã¬ããã«é¢é£ããé«åºŠãªãã¿ãŒã³ïŒ
oncurrency ïŒã䜿çšããå¿
èŠããããŸããããã§ãªãå Žåã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒ
U IïŒå€§å¹
ã«æžéãå§ããå®å
šãªãåçµãã«è³ãããšãããããŸãã
main threadãããªãœãŒã¹ãæ¶è²»ããã¿ã¹ã¯ãåé€ããå¿
èŠããããŸãã
main threadã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒ
UI ïŒã衚瀺ããã³ãŒããå®è¡ããŸãã
çŸåšã®ããŒãžã§ã³ã®
Swift 3ããã³æãè¿ã
Swift 4 ïŒ2017幎ç§ïŒã§ã¯ãããã¯ã
Swiftçµã¿èŸŒã¿èšèªã³ã³ã¹ãã©ã¯ãã«ãŸã é¢é£ä»ããããŠããªã2ã€ã®æ¹æ³ã§å®è¡ã§ããŸãããã®å®è£
ã¯ã
Swift 5 ïŒ2018幎æ«ïŒã§ã®ã¿éå§ãããŸãã
ãããã®1ã€ã¯
GCD (Grand Central Dispatch)ããã
åã®èšäºã¯ããã«å°å¿µããŠããŸãã ãã®èšäºã§ã¯ãOperationæäœã
Operationæäœãã¥ãŒãªã©ã®æœè±¡çãªæŠå¿µã䜿çšããŠã
iOSã¢ããªã±ãŒã·ã§ã³ã§
UIå¿çæ§ãå®çŸããæ¹æ³ã瀺ããŸãã ãŸããããã2ã€ã®ã¢ãããŒãã®éããšãã©ã®ç¶æ³ã§ã©ã¡ãã䜿çšããã®ãé©åãã瀺ããŸãã
ãã®èšäºã®ã³ãŒãã¯
Githubã§èŠãããšãã§ããŸãã
Operationãšã¯
Operationé©åãªå®çŸ©ã¯ã
NSHipsterã«èšèŒãããŠã
ãŸããOperationã¯å®äºããã¿ã¹ã¯ã§ãããæäœã®ç¶æ
ããã®åªå
床ãä»ã®Operationsããã®äŸåé¢ä¿ãã·ãã¥ã¬ãŒããããã®æäœã管çããããã®ã¹ã¬ããã»ãŒãæ§é ãæäŸããæœè±¡ã¯ã©ã¹ã§ãã
åºæ¬çãªæŠå¿µã Operation
æãåçŽãª
Operationã¯ãéåžžã®ã¯ããŒãžã£ã§è¡šãããšãã§ããããã
DispatchQueueã§å®è¡ã§ããŸãã ãã ãããã®åœ¢åŒã®æäœã¯ã
addOperationã¡ãœããã䜿çšããŠ
OperationQueue远å ããå Žåã«ã®ã¿é©çšã§ããŸãã
å®å
šãªæäœæäœã¯ã
BlockOperationã€ãã·ã£
BlockOperationã䜿çšããŠæ§ç¯ã§ããŸãã ç¬èªã®
start ()ã¡ãœããã䜿çšããŠ
start ()ãŸãã
åæé¢æ°ã®éåæããŒãžã§ã³ã®ãããªåå©çšå¯èœãªãã®ãååŸãããå Žåã
Operationã¯ã©ã¹ã®ã«ã¹ã¿ã
subclassãäœæãããã®ã€ã³ã¹ã¿ã³ã¹ãååŸããå¿
èŠããããŸãã
察å¿ãããã£ã«ã¿ãŒã䜿çšããŠãŒãããç»åãååŸãã
FilterOperationæäœã¯ã
Operationã¯ã©ã¹ã®ãŠãŒã¶ãŒ
subclassãšããŠå®çŸ©ãããŸãã ãŠãŒã¶ãŒã¯ã©ã¹ã«ã¯ãå
¥åããããã£ãšåºåããããã£ã®äž¡æ¹ãããã³ä»ã®ãã«ããŒé¢æ°ãå«ããããšãã§ããŸãã æäœã®æ©èœéšåã«å¯Ÿå¿ããããã«ã
main ()ã¡ãœãããåå®çŸ©ïŒ
override ïŒããŸããã
Operationã¯ã©ã¹ã䜿çšãããšã
OperationQueueæäœãã¥ãŒã§å°æ¥å®è¡ã§ããã¿ã¹ã¯ãäœæã§ããŸãããçŸæç¹ã§ã¯ãä»ã®
OperationsãããŸã§åŸ
æ©ã§ããŸãã
Operationã«ã¯
state mashine ãããã¯æäœ
Operation ãã©ã€ããµã€ã¯ã«ãã§ãã

æäœæäœã®å¯èœãªç¶æ
ã¯ã
pending ïŒä¿çïŒã
ready ïŒå®è¡æºåå®äºïŒã
executing ïŒå®è¡æžã¿ïŒã
finished ïŒå®äºæžã¿ïŒã
cancelled ïŒç Žæ£æžã¿ïŒã§ãã
OperationãäœæããŠ
Operationã«é
眮ãããšããæäœã
pendingèšå®ããŸãã ãã°ãããããšã
readyç¶æ
ã«ãªãããã€ã§ã
executingç¶æ
ã«ç§»è¡ããŠ
OperationQueueéä¿¡ããŠå®è¡ã§ããŸãã
executingç¶æ
ã¯ãããªç§ããæ°å以äžç¶ãããšããããŸãã å®äºåŸã
Operationã¯finalç¶æ
ã®
finishedé²ã¿ãŸãã ãã®åçŽãªãã©ã€ãããµã€ã¯ã«ã®ä»»æã®æç¹ã§ãOperationæäœã¯ç Žæ£ããã
cancelledç¶æ
ã«ãªããŸãã
Operationã¯ã©ã¹
APIã¯ã
Operationãã®ãã©ã€ããµã€ã¯ã«ããåæ ããŠããã以äžã«ç€ºãããŠããŸãã
start()ã¡ãœããã䜿çšããŠãOperationæäœãå®è¡ããããšãã§ããŸãããã»ãšãã©ã®å Žåã
OperationQueueæäœãã¥ãŒã«æäœã远å ãããšããã®ãã¥ãŒã¯èªåçã«æäœãéå§ããŸãã
start()ã䜿çšããŠ
start()ãããå¥åã®Operationæäœã¯ã
çŸåšã®ã¹ã¬ããã§åæçã«å®è¡ãããããšã«æ³šæããŠãã ããã
çŸåšã®ã¹ã¬ããã®å€éšã§å®è¡ããã«ã¯ã
OperationQueueãŸãã¯
DispatchQueueã䜿çšããå¿
èŠããããŸãã
ã¢ããªã±ãŒã·ã§ã³å
ã®ä»»æã®æç¹ã§ã®Operationæäœã®çŸåšã®ç¶æ
ã¯ãããŒã«ããããã£ã䜿çšããŠç£èŠã§ããŸãïŒ
isReady ã
isExecuting ã
isFinished ã
isCancelled KVO ïŒ
key-value observation ïŒã¡ã«ããºã ã䜿çšã
key-value observationæäœèªäœã¯ã©ã®ã¹ã¬ããã§ãå®è¡ã§ããæãå¿
èŠãªæ
å ±
main threadãŸãã¯æäœèªäœãå®è¡ãããã¹ã¬ãã以å€ã®ä»ã®ã¹ã¬ããã§ã
Operationæäœã®æ©èœã远å ããå Žåã¯ã
subclass Operationäœæããå¿
èŠããããŸãã æãåçŽãªå Žåããã®
subclassã¯ã
Operationã¯ã©ã¹ã®
main()ã¡ãœããããªãŒããŒã©ã€ãããå¿
èŠããããŸãã
Operationã¯ã©ã¹èªäœãæäœã®ç¶æ
ã®å€åãèªåçã«å¶åŸ¡ããŸããã以äžã«ç€ºãããè€éãªã±ãŒã¹ã§ã¯ããããæåã§è¡ãå¿
èŠããããŸãã
æäœã«ã¯ãæäœã®å®äºåŸã«å®è¡ããã
completionBlockãšã
OperationQueueã§ã®æäœã®åªå
床ã«åœ±é¿ãäžããããµãŒãã¹å質ã
qualityOfServiceãæäŸã§ããŸãã
ã芧ã®ãšããã
Operationã¯ã©ã¹ã«ã¯
cancel()ã¡ãœããããããŸããããã®ã¡ãœããã䜿çšãããš
isCancelledããããã£ã
trueèšå®ãããã ãã§ãæäœããåé€ããããšããæå³ã¯
subclass Operationäœææã«ã®ã¿æ±ºå®ã§ããŸãã ããšãã°ããããã¯ãŒã¯ããããŒã¿ãããŠã³ããŒãããå Žåã
cancel()ããããã¯ãŒã¯çžäºäœçšããæäœãåæãã
cancel()å®çŸ©ã§ããŸãã
åºæ¬çãªæŠå¿µã OperationQueue
èªåã§æäœãéå§ãã代ããã«ãOperationQueueãã¥ãŒã䜿çšããŠæäœã管çããŸãã Operation Queue
OperationQueueã¯ã远å ã®æ©èœãåãã
DispatchQueueåªå
床ã®é«ããã©ãããŒããšèŠãªãããšãã§ããŸããå®è¡ãããæäœãç Žæ£ããæ©èœãäŸåããæäœãå®è¡ããæ©èœãªã©ã§ãã
OperationQueueã¯ã©ã¹
APIèŠãŠã¿ãŸãããã

ããã§ã¯ã
OperationQueue ()æäœãã¥ãŒã®æãåçŽãªåæååãšã
OperationQueue ()ããã³
mainãã¥ãŒã®çŸåšã®æäœãã¥ãŒã決å®ãã
currentããã³
main 2ã€ã®ã¯ã©ã¹ããããã£ãåç
§ããŸããããã¯ã
GCD DispatchQueue.mainãšåæ§ã«ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒ
UI ïŒãæŽæ°ããããã«äœ¿çšãããŸã éåžžã«éèŠãªããããã£
maxConcurrentOperationCountã¯ããã®ãã¥ãŒã®åææäœã®æ°ãèšå®ãã
1ã«èšå®ãããšãæäœã®é 次ïŒ
serial ïŒãã¥ãŒã確ç«ããŸãã

ããã©ã«ãã§ã¯ã
maxConcurrentOperationCountããããã£ã®å€ã¯
Defaultã«èšå®ãããŸããããã¯ãåææäœã®æå€§å¯èœæ°ãæå³ããŸãã

OperationQueueæäœïŒãŸãã¯ãã®
subclassããããïŒã
Operation subclass ãã¯ããŒãžã£ãŒããŸãã¯æäœã®é
åå
šäœã«çŽæ¥è¿œå ããŠã
OperationQueueé
åå
šäœãå®äºãããŸã§çŸåšã®ã¹ã¬ããããããã¯ããããšãã§ããŸãã
Operation Queue
OperationQueueã¯ãåªå
床
qualityOfService ããæºåå®äºãïŒ
isReadyããããã£
isReady trueèšå®ãããŠ
true ïŒãããã³ä»ã®æäœããã®äŸåé¢ä¿ã«åŸã£ãŠãé
眮ãããæäœãå®è¡ã
true ã ããããã¹ãŠã®ç¹æ§ãçããå Žåãæäœã¯ãã¥ãŒã«å
¥ããããé åºã§ãå®è¡ãã®ããã«éä¿¡ãããŸãã æäœãæäœãã¥ãŒã«é
眮ããããšããããã®ãã¥ãŒã®ãããã«ãåã³é
眮ã§ããŸããã æäœãå®è¡ãããå Žåãæäœã®ãã¥ãŒã§ç¹°ãè¿ãå®è¡ããããšã¯ã§ããŸãããæäœã¯1åéãã§ãããããã£ãŠã
Operationã¯ã©ã¹ã®
subclassesãäœæããå¿
èŠã«å¿ããŠäœ¿çšããŠããã®æäœã®ã€ã³ã¹ã¿ã³ã¹ãååŸããŸãã
ããšãã°ãã¢ããªã±ãŒã·ã§ã³ãããã¯ã°ã©ãŠã³ãã¢ãŒãã§ãé¢ãããå Žåã
cancellAllOperations ()ã¡ãœããã䜿çšããŠããã¥ãŒå
ã®ãã¹ãŠã®æäœã«
cancel()ã¡ãã»ãŒãžãéä¿¡ã§ããŸãã
waitUntilAllOperationsAreFinished()ã¡ãœããã䜿çšããŠããã®ãã¥ãŒã«å¯Ÿãããã¹ãŠã®æäœãå®äºãããŸã§çŸåšã®ã¹ã¬ããããããã¯ã§ããŸãã ãã ãã
main queueãããå®è¡ããªãã§ãã ããã ãã¹ãŠã®æäœãå®äºããåŸã«ã®ã¿äœããè¡ãå¿
èŠãããå Žåã¯ãæäœã®
privateã·ãªã¢ã«ãã¥ãŒïŒ
serial queue ïŒãäœæããããã§æäœã®å®äºãåŸ
ã¡ãŸãã
OperationQueueæäœãã¥ãŒã¯
DispatchGroupããã«åäœããŸãã
OperationQueueã§ããŸããŸãª
qualityOfServiceããŠæäœã远å ã§ããŸãããããã¯åªå
床ã«åŸã£ãŠèµ·åãããŸãã ãŸããæäœãã¥ãŒå
šäœã«å¯ŸããŠ
qualityOfServiceãããé«ãã¬ãã«ã§èšå®ããããšãã§ããŸããããã®å€ã¯åäžæäœã®
qualityOfServiceã®å€ã«ãã£ãŠåå®çŸ©ãããŸãã
OperationQueueã®ããã©ã«ãã®
qualityOfServiceã¯
.backgroundã§ãã
isSuspendedããããã£ã
trueèšå®ããŠã
OperationQueueæäœã忢ããããšãã§ã
true ã ãã®ãã¥ãŒå
ã®æäœã¯ç¶è¡ãããŸããã
isSuspendedããããã£ã®å€ã
false倿ŽãããŸã§ãæ°ãã远å ãããæäœã¯å®è¡ã®ããã«éä¿¡ãããŸããã
isSuspendedããããã£ã®ããã©ã«ãå€ã¯
falseã§ãã
Playground Operationæäœãš
Operationãã¥ãŒã§ããã€ãã®å®éšãããŠã¿ãŸãããã
å®éš1. OperationQueueãäœæããŠã¯ããŒãžã£ãŒã远å ãã
ã³ãŒãã¯
Githubã® OperationQueue.playgroundã§è¡šç€ºã§ããŸãã
空ã®
printerQueueäœæã
printerQueue ã
ã¯ããŒãžã£ãŒã®åœ¢åŒã§æäœã
printerQueue ã
printerQueueã远å ãããšããã«ãæäœã¯çŸåšã®ã¹ã¬ããã«å¯ŸããŠéåæã«éå§ããã
readyç¶æ
ã«ãªããŸãã
waitUntilAllOperationsAreFinished()ã¡ãœããã䜿çšããŠãã¹ãŠã®æäœã®å®è¡æéãæšå®ããŸãããã®ã¡ãœããã¯ãçŸåšã®ã¹ã¬ããã«å¯ŸããŠãåæçã«ãæäœãå®äºãããŸã§åŸ
æ©ããŸãã ã¢ããªã±ãŒã·ã§ã³ã®
main queueã§ã¯ããããè¡ããªãæ¹ãè¯ãã§ããã
Playgroundã¯
U I
Playgroundäœãèµ·ããã
Playgroundäœè£ããããŸãã 7ã€ã®æäœãã¹ãŠã®åèšå®è¡æéã¯2ç§ããããããã«é·ãã
sleep(2)æŒç®åã®å®è¡æéã«å¯Ÿå¿ããããã
printerQueueã¯å€ãã®ã¹ã¬ããã§7ã€ã®æäœãã¹ãŠãåæã«éå§ããŸãã
printerQueueãã¥ãŒ
printerQueue倿Žãã
maxConcurrentOperationCountããããã£ã
2ã«èšå®ããŸãããã

ãã¢ã§éå§ããæåŸã®7çªç®ã®æäœã4çªç®ã®ããã¢ãã®1ã€ãéå§ããããããã¹ãŠã®æäœã
printerQueueã«çœ®ãã®ã«éåžžã«çãæéããããããã¹ãŠã®æäœãå®äºããã®ã«8ç§åŒ·ããããŸãã
次ã«ã
qualityOfServiceã
.userInitiatedå¢ãããå¥ã®
concatenationOperationæäœã远å ã
.userInitiated ã

æåã®æ©äŒã«ãåªå
床ã®é«ãæäœãä»ã®æäœãããæ©ãå®è¡ãããŸããããã¹ãŠã®æäœã®åèšå®è¡æéã¯å®è³ªçã«å€ãããªããŸãŸã§ã8ç§åŒ·ã§ãã
maxConcurrentOperationCountããããã£ã
1ã«èšå®ããŠã
maxConcurrentOperationCount serial maxConcurrentOperationCountãŸãããã

ãã®å Žåãæäœã¯é çªã«å®è¡ãããåªå
é äœãæ©èœããããã¹ãŠã®æäœã®åèšå®è¡æéã
16ç§ã«å¢å ããããšãããããŸãã
ãã£ã«ã¿ãŒåŠçããããœãŒã¹ç»åã®é
åãååŸããå Žåãããè€éãªã±ãŒã¹ãæ€èš

åã®ã»ã¯ã·ã§ã³ã§ããªãã¿ã®ã«ã¹ã¿ã
FilterOperationæäœã䜿çšãããŸãã

ãã£ã«ã¿ãŒæäœçšã®
filterQueue ããã£ã«ã¿ãŒåŠçãããã€ã¡ãŒãžãé
åã«è¿œå ããã¹ã¬ããã»ãŒãçšã®
appendQueueã·ãŒã±ã³ã·ã£ã«ïŒ
serial ïŒãã¥ãŒãäœæããŸãã å®éã«ã¯ãå€ãã®ãã£ã«ã¿ãªã³ã°æäœã
sharedãªãœãŒã¹ïŒ
filteredImagesé
åïŒã«åæã«ã¢ã¯ã»ã¹ããŠãèŠçŽ ã远å ããŸãã èŠããŠãïŒ
sharedãªãœãŒã¹ã倿Žããããã«
serial DispatchQueueãã¥ãŒã䜿çšããŸãããïŒ ãããåãã§ããã
Operationã«å¯ŸããŠå®è¡ãããŸãã ãã¡ãããã·ãªã¢ã«ïŒ
serial ïŒ
DispatchQueueãã¥ãŒã®æ¹ãå¹ççã§ãããã·ãªã¢ã«ïŒ
serial ïŒ
OperatioQueueãã¥ãŒã®äœæãšäœ¿çšã瀺ããŸãã
Swifté
åã¯
value typeãããã³ããŒæã«ã³ããŒïŒ
copy on write ïŒãããããããã«ãã¹ã¬ããã®å€æŽã«ã€ããŠå¿é
ããå¿
èŠã¯ãããŸããããç¹ã«é
åãåã¯ã©ã¹ã®ãªããžã§ã¯ãã®ããããã£ã§ããå Žåãããã«åé¡ããããã©ããã«ã€ããŠãã©ãŒã©ã ã«ã¡ãã»ãŒãžããããŸãã ãããã£ãŠãç°ãªãã¹ã¬ããã§æ°ããèŠçŽ ã远å ãããšãã«
thread safeé
åãä¿æããæ¹æ³ã瀺ããŸãã

次ã«ãåç»åã®ãã£ã«ã¿ãªã³ã°æäœãäœæããéåæå®è¡ã®ããã«
filterQueueã«è¿œå ããŸãã ãã£ã«ã¿ãŒåŠçãå®äºããããçµæã®ã€ã¡ãŒãžã
filteredImagesé
åã«è¿œå ãã
completionBlockã§
appendQueueãŸããããã§å¥ã®æäœãã¥ãŒ
appendQueueã䜿çšããŸãã
completionBlockå
¥åãã©ã¡ãŒã¿ãŒ
completionBlockãªããäœãè¿ããŸããã
ãã¹ãŠã®ãã£ã«ã¿ãªã³ã°æäœãå®äºããã®ãåŸ
ã£ãŠããã£ã«ã¿ãªã³ã°ãããç»åé
åã確èªããŸãã

ãã¹ãŠã®æäœã®å®è¡æéã¯
1.19ç§ã§ããããã¯ã1ã€ã®æäœïŒåã®ã»ã¯ã·ã§ã³ãåç
§ïŒã®å®è¡æéã«å¹æµããŸãã
filterQueue ã
filterQueueãã¥ãŒã§æäœã®ãã«ãã¹ã¬ããå®è¡ãè¡ãããŸãã
Playgroundã¯ããã£ã«ã¿ãªã³ã°ãããç»åã®é
åã衚瀺ãããŸããããã£ã«ã¿ãªã³ã°å¹æãèŠãã«ã¯éåžžã«å°ããã§ãã ã¯ã€ãã¯ãã¥ãŒãã¿ã³ãã¯ãªãã¯ããŠããã£ã«ã¿ãªã³ã°å¹æã確èªã§ããŸãã

éåææäœ
ã³ãŒãã¯
Githubã® AsyncOperations.playgroundã§è¡šç€ºã§ããŸãã
ãããŸã§ã®ãšãããSYNCHRONOUSã¿ã¹ã¯ã®æäœãã€ãŸãçŸåšã®ã¹ã¬ããã䜿çšããã¿ã¹ã¯ãå®äºãããŸã§æ»ããªã颿°ã䜿çšããŸããã ASYNCHRONã®ã¿ã¹ã¯ïŒé¢æ°ïŒã¯ãŸã£ããç°ãªãæ¹æ³ã§åäœããŸãïŒçŸåšã®ã¹ã¬ããã§ããã«å¶åŸ¡ãè¿ããå¥ã®ã¹ã¬ããã§ã¿ã¹ã¯ãå®è¡ããã¿ã¹ã¯ãå®äºããããšãç¥ããããããä»ã®ã¹ã¬ããã§
completionHandlerãéããããŸãã å
žåçãªäŸã¯
URLSessionã§ãïŒ

Operationæäœã§
URLSessionã®æ©èœããã©ãããã§ããŸãããæäœã®ã¹ããŒã¿ã¹ãæåã§å¶åŸ¡ããå¿
èŠããããŸãã
SYNCHRONOUS颿°ã®ã«ã¹ã¿ã æäœãäœæããã«ã¯ãæäœã¡ãœãã
main()ããªãŒããŒã©ã€ãããã ãã§æžã¿ãŸããã ASYNCHRON颿°ã§ãŸã£ããåãããšãè¡ãå Žåã
main()ã§ããã«å¶åŸ¡ãçŸåšã®ã¹ã¬ããã«æ»ããå¥ã®ã¹ã¬ããã§åäœããããã«ãè±éããã
main()ã¡ãœããã®æåŸã«ç§»åãã
OperationQueueããã«
OperationQueueãã¥ãŒãããã¹ããŒãããŸãã ASYNCHRONæ©èœãå®äºããããšã¯ãããŸããã ããã
OperationQueueèåŸã«ããããžãã¯ã§ãã
éåææäœã«ã¯ããŸã£ããç°ãªãäœæ¥ããžãã¯ããããŸãã

æäœããæºåå®äºãïŒ
isReady = true ïŒã®å ŽåãOperationQueueæäœãã¥ãŒã¯
start()ã¡ãœãããåŒã³åºããŸãããã®ã¡ãœããã§ã¯ãæäœããrunningãç¶æ
ïŒ
isExecuting = true ïŒã«èšå®ãã
main()ã¡ãœãããåŒã³åºããŸãããã®ã¡ãœããã¯ASYNCHRON颿°ãåŒã³åºããŸãã ASYNCHRON颿°ã¯ANOTHERã¹ã¬ããã§äœããè¡ããŸããã
isExecutingããããã£ã¯ãCURRENTã¹ã¬ããã§äœãè¡ãããå¥ã®ã¹ã¬ããã§å®è¡ãããŠããã¿ã¹ã¯ã®ã¿ã衚ãå Žåã§ã
trueãŸãŸã§ãªããã°ãªããŸããã ASYNCHRON颿°ãASYNCHRON颿°ã®
completionHandlerã瀺ã
completionHandleråŒã³åºãå Žåã
completionHandlerããããã£
isFinishedã
trueã«ã
isExecutingããããã£ã
falseèšå®ããå¿
èŠããã
false ã
ãããã£ãŠãASYNCHRONæäœã®å Žåã
main()ã¡ãœãã以äžã®ãã®ããªãŒããŒã©ã€ãããå¿
èŠããããŸãã æ¬¡ã®ã¡ãœãããšããããã£ããªãŒããŒã©ã€ãããå¿
èŠããããŸãã

Operationããç¶æ¿ãããASYNCHRONOUSæäœã®å®è¡ã«é©ããæœè±¡ã«ã¹ã¿ã ã¯ã©ã¹
AsyncOperatonäœæããŸãããã ãã®æœè±¡æ§ã¯ãéåææäœãå®è¡ãã
main()ã¡ãœããããªãããšã§ãã 圌ã®å³ã¯æ¬¡ã®ãšããã§ãã
OperationQueueãªãã§èªåã§ASYNCHRONOUSæäœã䜿çšããå Žåã
isAsynchronousããããã£ããªãŒããŒã©ã€ãããŠ
trueãè¿ãå¿
èŠããããŸãã ASYNCHRON颿°ãå®éã«éå§ãã
isExecutingããããã£ã
trueä¿ã€ã«ã¯ã
start()ã¡ãœããããªãŒããŒã©ã€ãããå¿
èŠããããŸãã ãŸããæäœã®ç¶æ
ãæ±ºå®ããããããã£
isReady ã
isExecuting ã
isFinishedã管çããæ¹æ³ãåŠã¶å¿
èŠããããŸãã ãããã®ããããã£ã¯ã
OperationQueueæäœãã¥ãŒã«ãã£ãŠäœ¿çšããã
OperationQueueã®ã¹ããŒã¿ã¹ãç£èŠããäŸåããæäœã®å®è¡ãæŽçããŸãã
æäœéã®äŸåé¢ä¿ãå®çŸ©ããå Žåã1ã€ã®æäœãå¥ã®æäœãéå§ããåã«çµäºããå¿
èŠãããããã
OperationQueueæäœãã¥ãŒã¯ãæäœããã€çµäºããããç¥ãããšãéèŠã§ãã SYNCHRONOUSæäœã®å ŽåãSYNCHRONOUSæ©èœãçµäºãããšSYNCHRONOUSæäœãçµäºãããããããã¯åé¡ã§ã¯ãããŸããã ãã ããASYNCHRON颿°ã¯çŸåšã®ã¹ã¬ããã®å€åŽã§çµäºãããããASYNCHRON颿°ã®å®éã®çµäºã«ã€ããŠ
OperationQueueæäœãã¥ãŒã«éç¥ããæ¹æ³ãå¿
èŠã§ãã
GCDãæãåºããšãASYNCHRONOUS颿°ãã°ã«ãŒãã«è¿œå ãããšãã«ã
enter()ããã³
leave()ã¡ãœããã䜿çšããŠãASYNCHRONO颿°ã®éå§ãšçµäºãæç¢ºã«ç€ºããŸããã ãã ããOperationæäœã®å Žåãæäœã«ã¯
isReady ã
isExecuting ã
isFinished ã
isCancelledãªã©ã®ç¶æ
ããããããç¶æ³ã¯ã¯ããã«è€éã§ã
isReady颿°ãOperationæäœã«è¿œå ããå Žåããããã®ç¶æ
ãæåã§ç®¡çããå¿
èŠããããŸãã ãã®äœæ¥ã容æã«ããããã«ã
AsyncOperatonãšããååã®
Operationã¯ã©ã¹ã®ç¹å¥ãªæœè±¡ãŠãŒã¶ãŒ
subclassãäœæããŸããããã®äž»ãªã¿ã¹ã¯ã¯ãæäœã®ç¶æ
ã®å€æŽãå¶åŸ¡ããããšã§ãã ç¬èªã®ASYNCHRON颿°ã®å Žå
subclassã¯ã©ã¹ã®
subclassäœæããããããASYNCHRON颿°ãåŒã³åºã
main ()ã®ã¿ãå®çŸ©ããŸãã ãããŠããã§ã«ãã®æ°ããæäœã¯
OperatonQueueã«è¿œå ãã
OperatonQueue ã
ãã ããåé¡ã¯ãããšãã°ãæäœã®ç¶æ
ã«é¢é£ãããã¹ãŠã®ããããã£
isReady ã
isExecuting ã
isFinishedã
readonly ïŒ
{get} ïŒã§ãããçŽæ¥èšå®ã§ããªãããã
isExecuting = trueèšè¿°ã§ããªãããš
{get} ã
AsyncOperatonæäœã®ã¹ããŒã¿ã¹
AsyncOperaton倿Žãããããšãã·ã¹ãã ã«éç¥ããªããã
isExecutingããããã£ã
trueè¿ãããã«ããããšããã§ããŸããã
Operationã¯ã©ã¹ã¯ã
KVO ïŒ
key-value observation ïŒã¡ã«ããºã ãš
willChangeValueForKeããã³
didChangeValueForKeyã
isReady ã
isExecuting ã
isFinished ã
isExecutingãªã©ã®ç¶æ
ããããã£ã®å€æŽã«ã€ããŠéç¥ããŸãã
ãããã£ãŠãè³ç£ç®¡çæ¥åã®äŸ¿å®ã®ããã«ãç§ãã¡ã¯ãæ°ããããŒã¿åãäœæããŸã-é©åãªåæenum Stateéåææäœç¬èªã®å€çš®ã®ç¶æ
ã衚ãããã«ïŒreadyãexecutingãfinishedãåæStateã«ã¯ãKVOéç¥ã®ã¹ã€ãããšããŠäœ¿çšfileprivateããååã®ããããã£ãå«ãŸããŸããããããã£ã¯èšç®ããã倧æåã®åæèŠçŽ ã®ååã§ããã«æ¥ç¶ãããæååã§æ§æãããŸããæ¬¡ã«ãæœè±¡ã¯ã©ã¹ã§æäœã®çŸåšã®ç¶æ
ã衚ãå倿°ãå®çŸ©ããŸããããã©ã«ãã§ã¯ããã®å€ã¯equal ã§ãã倿°ã倿Žãããã³ã«ãKVOéç¥ãåãæ¿ããå¿
èŠããããŸãããããè¡ãã«ã¯ããªãã¶ãŒããŒãšããããã£ã䜿çšããŸããkeyPathkeyPath"is"rawValueStateAsyncOperatonvar stateStatereadystatewillSet {}didSet {}statestateããšãã°ãããexecutingã«æäœç¶æ
ãåãæ¿ããåã«ãäž¡æ¹ã®æäœã®æ°ããç¶æ
ïŒïŒãšçŸåšã®ç¶æ
ïŒïŒã«ã€ããŠKVOéç¥finishedãéä¿¡ããå¿
èŠããããŸããåãæ¿ãæ¡ä»¶ãåŸã«çºçãããæã
ã¯éä¿¡KVOã®éç¥ãããããã«äž¡æ¹ã®æ¡ä»¶ïŒïŒïŒãšïŒïŒãããã¯ãã·ã¹ãã ãæ°ããå€ããã€ãã£ããã®ç¶æ
倿°ã®èªã¿åºãåäœãããããã«ãªããŸãããããã®ãããéåææäœæã
ã¯ããã€ãã£ããç¶æ
倿°ã®æäœãåå®çŸ©ããå¿
èŠãããããwillChangeValuenewValuefinishedstateexecutingstatedidChangeValuekeyPatholdValueexecutingstatefinishedisReadyisExecutingisFinishedAsyncOperationisReadyisExecutingisFinishedstateæ£ããå€ãè¿ãèšç®å€æ°ãšããŠæ°ããããããã£ã䜿çšããŸãããããextensionã¯ã©ã¹æ¡åŒµã§è¡ãAsyncOperationãŸãïŒããæç¹ã§ãæäœã®ããããã£isReadyãçãããªãtrueãããããã£isReadyforã䜿çšããå¿
èŠããããŸããããã¯ãä»ã®æäœsuperclassãžã®äŸåæ§ïŒdependenciesïŒããç¥èŠãããŸããç¬èªã®ããžãã¯ãšã®ããããã£isReadyãçµã¿åãããsuperclassããšã§ãæäœãæ¬åœã«ãæºåå®äºãã§ããããšã確èªã§ããŸããæ³šå€æ°ãããã°ããstateã§.finishedãã®ããããã£superclass isFinishedãšåãtrueããšããããã£isExecuting- falseããŸãã2ã€ã®ã¡ãœãããisAsynchronousè¿ãããšã§ããããã£ãåå®çŸ©ããŸãtrueïŒstart()ãšcancell()ãã¡ãœããã§start()ã¯ãæäœãç Žæ£ãããŠãããã©ãããã€ãŸãããããã£isCancelledãequalã§ãããã©ããã確èªããŸãtrueããã®å Žåã倿°ã«æ°ããå€ãèšå®ããå¿
èŠããããŸãstate- .finishedãæäœãç Žæ£ãããªãå ŽåããåŒã³åºããŸãmain()ãããã¯èŠããŠããmain()éåæé¢æ°ã§ãããããã¯ããã«æ»ããŸãã®ã§ãæã
ã¯æåæäœã®ç¶æ³ãèšå®ããå¿
èŠãstatåãã§ã.executingã ASYNCHRON颿°ãæ»ããšããcompletionHanlleræäœã®ç¶æ
ãèšå®ããªããã°ãªããŸãã.finishedã ASYNCHRON颿°ã®å Žåãstart()ã¡ãœããã§superclass-ã®åæ§ã®ã¡ãœããã®åŒã³åºãã䜿çšã§ããªãããšãèŠããŠããããšãéåžžã«éèŠã§ããããã¯super.start()ã颿°ã®åæèµ·åãæå³ããmain()æ£å察ãå¿
èŠã ããã§ãããã®ã¡ãœããã§cancell()ã¯ãæäœã®ç¶æ
ãèšå®ããå¿
èŠããããŸã.finishedããã®çµæãæœè±¡ã¯ã©ã¹ãååŸããŸããAsyncOperationãç¬èªã®éåææäœã«äœ¿çšã§ããŸãããããè¡ãã«ã¯ãæ¬¡ã®æé ãå®è¡ããŸããäŸãšããŠãsleep (1)2ã€ã®æ°å€ã®éåæäœéïŒå
éšã«ããïŒå ç®ã®æ©èœã䜿çšããŸããAsyncOperationas ã䜿çšããŠsuperclassãåå®çŸ©main ()ããæäœç¶æ
stateã.finishedin ã«èšå®ããããšãå¿ããªãã§callbackãã ããïŒcallbackãªã¿ãŒã³ã®çµæresultãæã
ã¯ããããã£æäœå²ãåœãŠãself.resultããã³ã»ããåäœç¶æ
ã®stateæã«.finishedããšãéç¥çªå·ã®éåææ·»å çµäºã®ãã¹ãŠã®æäœãããŠããã¯ããã®æäœã§äœæ¥ããå¿
èŠããããŸããã䜿çšããŠSumOperationãæ°å€ã®ãã¢ã®åèšã®é
åãååŸããŸããæ°å€ã®ãã¢ããšSumOperationã«ãadditionQueueéåžžã®æ¹æ³ã§æäœãäœæããæäœã®ãã¥ãŒã«é
眮ããŸãéåææäœã®é åºã¯ãé
åå
ã®æ°å€ã®ãã¢ã®é åºãšã¯ãããã«ç°ãªãããšãããããŸããããã¯ãéåææäœã®ãã«ãã¹ã¬ããå®è¡ã瀺ããŠããŸãã第äºã®äŸã¯ãäžããããç»åã®éåæããŒãã£ã³ã°ã«é¢ããURLä»ãURLSessionïŒ
éåæåäœäœæImageLoadOperationååã®ããã«ã¯ã©ã¹ã®ãµãã¯ã©ã¹ã§ããã AsyncOperationãæäœã«ã€ããŠã¯ImageLoadOperationãååã®ããã«ãåå®çŸ©main ()ãããã³æäœã®ã¹ããŒã¿ã¹ãèšå®ããããšãå¿ããªãã§ãã ããstateäž.finishedã§completionïŒ
æäœãäœæãoperationLoadãç»åãååŸoperationLoad.outputImageããäžã«è¡šç€ºviewïŒ
ã³ãŒãã¯ãäžã§é²èЧããããšãã§ããŸãAsyncOperations.playgroundã§ã®GithubãäŸåé¢ä¿ïŒdependenciesïŒ
ã³ãŒãã¯Githubã® LoadAndFilter.playgroundã§è¡šç€ºã§ããŸãããã®ã»ã¯ã·ã§ã³ã§ã¯ã1ã€ã®æäœã®çµæãå¥ã®æäœã«è»¢éããæåã®æäœãçµäºãããšãã«ã®ã¿2çªç®ã®æäœã匷å¶çã«éå§ããæ¹æ³ãæ€èšããŸãã
å³ã§ã¯ã2ã€ã®æäœã衚瀺ãããŸãã1ã€ç®ã¯ãããã¯ãŒã¯ããç»åãèªã¿èŸŒã¿ã2ã€ç®ã¯ç»åã®äžéšãšäžéšã®ããã©ã®ã³ã°ããå®è¡ããŸã-ãã£ã«ã¿ãªã³ã°ããããã®æäœã¯äž¡æ¹ãšãçžäºã«éåžžã«ããŸãæ©èœããŸããã€ã¡ãŒãžã®ãããŠã³ããŒããŒãã¯ãã®ããŒã¿ãããã£ã«ã¿ãŒãã«çŽæ¥è»¢éããŸãããããã®äž¡æ¹ã®æäœãå«ã1ã€ã®æäœãäœæã§ããŸãããããã¯éåžžã«æè»ãªèšèšã§ã¯ãããŸããã
ã¢ããªã±ãŒã·ã§ã³ã®ããŸããŸãªå Žæã§ã€ã¡ãŒãžãä»»æã®é åºã§äœ¿çšããããã«ãã€ã¡ãŒãžãæäœããéã«ãæäœã®ã¢ãžã¥ãŒã«æ§ãããçšåºŠç¢ºä¿ããããšãæãŸããã§ããããæè»ãªãœãªã¥ãŒã·ã§ã³ã¯ãæåã®æäœãã2çªç®ã®æäœãžã®ã€ã¡ãŒãžã®è»¢éã䌎ãæäœã®ããã§ãŒã³ãã®å®è£
ã«é¢é£ä»ããããŠããŸãã ããã£ã«ã¿ãŒãã¯ãããŒããŒãã«äŸåããŠãããšå€æã§ããæäœã®ãã¥ãŒã¯OperationQueueãããã£ã«ã¿ãŒããreadyãããŒããŒãã®çµäºåŸã«ã®ã¿ç¶æ
ã«èšå®ãããããšãèªèããŸããããã¯æ¬åœã«æäœãã¥ãŒã®ãã°ããããèœåãã§ãOperationQueueã ãäŸåé¢ä¿ãã®éåžžã«è€éãªã°ã©ããäœæããŠãOperationQueueå¿
èŠã«å¿ããŠèªåçã«æäœãéå§ããããšãã§ããŸãããäŸåé¢ä¿ãã®åŠçããµããŒãAPIããã¯ã©ã¹OperationïŒdependenciesïŒ-éåžžã«ã·ã³ãã«ã§ãããæäœäžã«çŽ æŽãããåãçºèŠããŸãã
ãäŸåé¢ä¿ãïŒdependencyïŒã远å ããã³åé€ãããdependenciesããã®æäœã«è¿œå ããããäŸåé¢ä¿ãã®ãªã¹ããååŸãããã§ããŸãã以äžã§ã¯ããªã¹ãdependenciesã䜿çšããŠãäŸåãã£ã«ã¿ãªã³ã°æäœã®å
¥åç»åãååŸããŸããäŸåé¢ä¿ãäœæãããšããããããã¯ïŒdeadlockïŒãçºçããå¯èœæ§ãé«ããªã
ãŸãããäŸåé¢ä¿ãåã«éããã«ãŒããçŸãããšããããããã¯ãçºçããèŠèŠçãªåæã«ãã£ãŠç¹å®ãã以å€ã«ãããããæé€ããæ®éçãªæ¹æ³ã¯ãããŸãããæäœã®ãäŸåæ§ãã«é¢é£ããæ¬¡ã®åé¡ã¯ããäŸåæ§ãã§ãŒã³ãã«æ²¿ã£ãŠããŒã¿ã転éããæ¹æ³ã§ããããšãã°ãäžèšã®äŸã§ã¯ããããŒããŒããæåã«æ©èœããæ¬¡ã«ããã£ã«ã¿ãŒããæ©èœããå Žåãå
¥åã€ã¡ãŒãžã¯ãããŒããŒãã®åºåã€ã¡ãŒãžã«ãªããŸãããããã©ã®ããã«éæããŸããïŒãã®ImagePasså Žåãå¿
èŠãªããŒã¿ãæäŸãããããã³ã«ãäœæããŸãUIImage? ïŒ
ããŒããŒã -ãã§ã«ããªãã¿ã®ã¯ã©ã¹ã®ImageLoadOperation圌ã¯äžããããå
¥ãå£ã«ã¯ãããã¯ãŒã¯ã®ã€ã¡ãŒãžããŒãæäœãURLæååãªã©ã®ç»åurlStringãããã³åºå-ã€ã¡ãŒãžãã®ãã®outputImageã
ã¯ã©ã¹ImageLoadOperationã確èªããããã³ã«ImagePassãšãããã³ã«ã®ç¹æ§ãè¿ãimageåºåã¯ç»åãèªã¿èŸŒãŸoutputImageãã¿ãŒã³ã§ã¯ãæäœããã£ã«ã¿ãªã³ã°ã -ã¯ã©ã¹ãFilterOperation-å
¥åç»åãååšããªãå Žåã«ã¯ã_inputImageäŸåæ§ã®ç¢ºèªããdependenciesãšã ã人ã
ã«èå³ãæã£ãŠããã確èªãã¬ããŒãImagePass圌ã¯äŸåãšããŠç¬¬1ã®åäœãéžæããæœåºç©ããããinputImageïŒ
ããã£ã«ã¿ããå
¥åã§-å
¥åç»åinputImageãåºåã¯é¢æ°ã䜿çšããŠãã£ã«ã¿ãŒåŠçãããfilterImage (image:)ç»åoutputImageã§ããããã¯éåžžã®åææäœãªã®ã§ãåå®çŸ©ããã ãã§æžã¿ãŸãmain()ãããã£ã«ã¿ãŒãinputImageããããŒããæäœã®åºåã€ã¡ãŒãžãå
¥åã€ã¡ãŒãžãšããŠäœ¿çšããããã«ãããã2ã€ã®æäœã飿ºãããããšæããŸãããããè¡ãããã«ãæã
ã¯ããã£ã«ã¿ãªã³ã°ã®åäœãèšå®ãfilterãå€ã§nilïŒ
ã³ãŒããäžã«é
眮ãããŠããLoadAndFilter.playgroundäžã®Githubãäžã®æäœã®ç Žå£ OperationQueue
ã³ãŒããäžã«é
眮ãããŠããCancellation.playgroundäžã®Githubããã¥ãŒã®å¥ã®çŽ æŽãããOperationQueueæ©äŒãèŠãŠã¿ãŸããã-ãªãã¬ãŒã·ã§ã³ãç Žå£ããèœåãæäœOperationããã¥ãŒã«é
眮ããåŸã¯ãæäœãOperationQueueå®è¡ããããã®ç¬èªã®èšç»ããããæäœãå®å
šã«å¶åŸ¡ãããããæäœãå®è¡ããæ¹æ³ã¯ãããŸããããã ãOperationãã¡ãœããã䜿çšããŠç Žæ£ããããšãã§ããŸãcancel()ã
ã¡ãœãããåŒã³åºãcancel()ãšããã«æäœã忢ãããšæããããããŸããããããã§ã¯ãããŸããããã®ã¡ãœããcancel()ã¯ãisCancelledæäœããããã£ãã«èšå®ããã ãtrueã§ããæäœããŸã éå§ãããŠããªãå Žåãããã©ã«ãã®æ¹æ³start()æäœã®å®è¡ãèš±å¯ãããããããã£isFinishedãã«èšå®ããŸãtrueãããªãã¯ïŒãªãŒããŒã©ã€ãããå ŽåoverrideïŒã®æ¹æ³ãstart()ãããªãã¯ããªãã®èœåä¿åããªããã°ãªããªãstart()財ç£ã®ååŒãããã°ãæäœã®å®è¡ã鲿¢ããããisCancelledã«èšå®ãããŠãããtrueããããŠãæœè±¡ã¯ã©ã¹ãèŠããšãAsyncOperationãŸãã«ãããè¡ã£ãŠããããšãããããŸããããã«ãmain()æäœã¡ãœããã§ãç¹ã«äœéãŸãã¯ãªãœãŒã¹éçŽçãªåŠçãå®è¡ããåã«isCancelledãæäœãæ¢ã«ç Žæ£ãããŠãããã©ãããããããã£ã§ãã¹ãããå¿
èŠããããŸããæäœãç Žæ£ãããtrueããããã£ã®å€ã衚瀺ãããå ŽåãæäœisCancelledã忢ããããã«å¿
èŠãªã¢ã¯ã·ã§ã³ãå®è¡ããå¿
èŠããããŸããæäœã®å ŽåOperationããšãã°ãç»å倿ãªã©ã®ããŒã«ã«ã§å®è¡ããå Žåãæäœã忢ã§ããŸãããµãŒããŒããç»åãããŠã³ããŒããããªã©ããããã¯ãŒã¯ãžã®ã¢ã¯ã»ã¹ã«é¢é£ããæäœã®å ŽåããµãŒããŒãçµæãè¿ããŸã§ãã®ãããªæäœã忢ããããšã¯ã§ããŸãããæäœã®ããŸããŸãªãã¹ããããã®éã«ãããžãã¯ãã远å ããŠããã®æäœãå®è¡ãç¶ãã䟡å€ããããã©ããããŸãã¯æäœãisFinishedçäŸ¡ç¶æ
ã«èšå®ãã䟡å€ããããã©ããã確èªããå¿
èŠãããtrueãŸããæäœãåé€ããããã«èšèšããAPIãã¯ã©ã¹Operationã¯éåžžã«åçŽã§ã2ã€ã®äœçœ®ã®ã¿ã§æ§æãããŸããã¡ãœãããåŒã³åºãcancel()- isCancelledæäœããããã£ãã«èšå®ãtrueãŸããã¡ãœãããåŒã³åºããããšãã«ããšã«æ³šæããããšãéèŠã§ããcancel()ãããããã£isExecutingãšisFinishedãã§å€åfalseããtrueãããããæäœãisCancelled = trueçµäºããã«ïŒïŒç Žå£ãããããšã¯å®å
šã«æ£åžžã§ãisFinished = trueãããããã£isCancelledã¯ã忢ããå¿
èŠãããããšãæäœã«äŒããããããã£ã¯ãisFinishedæäœãæ¢ã«åæ¢ããŠããããšãã·ã¹ãã ã«äŒããŸããç§ãã¡ã®æœè±¡éåææäœã¯ãAsyncOperationã¡ãœããããªãŒããŒã©ã€ããcancel()ãåäœç¶æ
ãèšå®ããæ¹æ³ã«stateã.finishedãŠããã®ãããªå€æŽã¯ã倿޿äœã®ããããã£ãèµ·ããisFinishedãšisExecutingïŒãã¥ãŒOperationQueueã¯ãã¹ãŠã®æäœãç Žæ£ã§ããŸããäŸãšããŠããã€ãã®ã«ã¹ã¿ã æäœã䜿çšããŠãã¡ãœããåŒã³åºãã«æ£ããå¿çããæäœãååŸããæ¹æ³ãèŠãŠã¿ãŸãããcancel()ãã³ãŒããäžã«é
眮ãããŠããCancellation.playgroundäžã®Githubãæäœã«ArraySumOperationã¯ãinputArrayæŽæ°ã®ãã¢ã§æ§æãããã¿ãã«ã®å
¥åé
åãããoutputArrayãåºåã§ãããã®åèšã®é
åã圢æããŸãã
æ°å€ã®åãã¢ã«å¯ŸããŠãCancellation.playgroundslowAddã®ãã©ã«ããŒSourceã«ãããé
ããå ç®é¢æ°ã䜿çšããåºåé
åã«è¿œå ããŸããæ°å€ã®å
¥åé
åãèšå®ããæäœã圢æããæäœãã¥ãŒã«è¿œå ããŸãoutputArraysumOperationqueueã¿ã€ããŒãèµ·åãsumOperationãŸãcancel()ãããã«ãããã¡ãœããåŒã³åºãã«å¯Ÿããæäœã®åå¿ã確èªã§ããæéãããã«èª¿æŽã§ããŸããããã«ãæäœã«ã¯completionBlockãã¿ã€ããŒã忢ãPlayground outputArrayãæäœããã€ã³ãããŠçµäºããŸãPlaygroundïŒ
ãã®ãããæäœãå®äºããã«ã¯sumOperation5ç§ä»¥äžããããŸããä»åŒã³åºãããšã«ãã£ãŠéå§ããåŸã2ç§åŸã«ããã®æäœãç Žå£ãããcancel ()ïŒ
ç§ãã¡ã¯ãäºæããªãçµæãåŸãŸãã-æäœãsumOperationå®å
šã«ç¡ç Žå£æäœãçºçããŠããªããå®è£
ãããŠããŸããåé¡ã¯äœã§ããïŒ
ããããå®éã«ã¯ãã¡ãœããcancel ()ã¯ããããã£isCancelledãtrueã«èšå®ããã ãã§ãããæäœã®åé€ã«å¿
èŠãªã¢ã¯ã·ã§ã³ã¯æäœã®éçºè
ã«å§ããããŸããããããã£ãã«isCancelledèšå®ãããŠãããšããäºå®ã«å¯Ÿå¿ããå¿
èŠããããŸãtrueãåºåé
åã«åèšã远å ããåã«ãæäœãç Žæ£ããããã©ããã確èªããŸãããããŠããããç Žå£ãããå Žåããµã€ã¯ã«ãäžæããŸãïŒ
åéããŸãããPlaygroundïŒ
2ç§ããå°ãé
ããŠåæ¢ãã2ã€ã®éãååŸããŸãã.3çªç®ã®éãååŸããããšãããšãã«ãæäœã®ç Žå£ã«é¢ããã·ã°ãã«ãååŸããéã®ãããªãåä¿¡ã忢ããŸããããã®äŸã¯ãã³ãã³ãã«å¯ŸãããŠãŒã¶ãŒæäœã®å¿çãååŸããæ¹æ³ãæç¢ºã«ç€ºããŠããŸãcancel ()ãã¿ãã«é
åãä»ããŠåºåé
åã«ãŒããååŸããããã«AnotherArraySumOperationå¥ã®é¢æ°ã䜿çšãããç¹ã§ç°ãªãå¥ã®æäœãèŠãŠã¿ãŸãããslowAddArrayïŒ
åã®ã±ãŒã¹ãšã®éãã¯ãã¿ãã«é
åã®èŠçŽ ãä»ããã«ãŒããmain()æäœã¡ãœããã§ã¯ãªããå¥ã®é¢æ°ã§ãããç§ãã¡ã«ãšã£ãŠé£ããããšã§ãæäœãç Žæ£ãããå Žåããµã€ã¯ã«ãäžæããŸããããããéåžžã«æŽç·Žããããã®ã§ã¯ãããŸããããã®ãããªå¯èœæ§ããããŸãïŒ
颿°ã®å
¥åã«ã¯ãæŽæ°slowAddArrayã®inputãã¢ã®é
åã«å ããŠãåŒæ°ããããŸãprogressãããã¯Optionalãé
åã®åŠçã®æ·±ããåŒæ°ãšããŠåããDouble(results.count) / Double(input.countãããè¿ã颿°ã§ãBoolãããBoolã«ãããã¢ã¬ã€ã®ç¶ç¶åŠçãæ±ºå®ãããŸããæ¹æ³ã§main()æäœAnotherArraySumOperationïŒåã®å³ïŒã§ã¯ã颿°ã«slowAddArrayé
åãæž¡ããŸãããinputArrayåŒæ°ã¯progressããããŒã«ãã¯ããŒãžã£ãŒãšããŠèšèšãããŠãããprogresså°å·ã«ããããã£ã䜿çšããŸãããããããã£progressã¯Doubleã§ãã®ã§ã100ãä¹ç®ããé
ååŠçã®å®äºçãšæäœã®å®äºçãååŸããŸãããæ¬¡ã«ãæäœã®ç Žæ£ã«å¯Ÿããå¿çãè¿ããŸããããã¯ãé
åã®åŠçãç¶è¡ãŸãã¯äžæããä¿¡å·ã§ããåå¿ã¯ããããã£ã®éã§ãisCancelledãçŽåã®æäœãå
ã«æ»ãSumOperationãæ°ããªæäœäžAnotherArraySumOperationïŒ
éç¶ç¶äºæ¥ãããåŸ2ç§ãæã
ã¯åãçµæãåŸã-æã
ã ãæ±ãããšãã§ãã2ã®é
åã«5- æäœãç Žæ£ãããåãã€ãŸã40ïŒ
ãæäœäžæé
å»¶ã4ç§ã«èšå®ããŸãã5ã®é
åã®4ã€ã®èŠçŽ ãã€ãŸã80ïŒ
ã¯ãæäœãç Žæ£ã
ããåã«åŠçãããŸãããåã
ã®æäœãããããã£ã«å¿çãããããç Žæ£ã§ããããšã確èªããããšãéåžžã«éèŠã§ãããããããã®æ¹æ³ã䜿çšããŠãåã
ã®ååŒã®ç Žå£ã«å ããŠãããªãã¯ãã¥ãŒæäœã«ãã¹ãŠéå§ã®æäœãåé€ããããšãã§ããŸãæ¹æ³ã䜿çšããŠisCancelledcancel ()OprationQueuecancellAllOperationsãããã¯ãåäžã®ç®çã§æ©èœããäžé£ã®æäœãããå Žåã«ç¹ã«åœ¹ç«ã¡ãŸãããã®ç®æšã¯ãè€æ°ã®ç¬ç«ããæäœã䞊è¡ããŠå®è¡ããããšããŸãã¯æ¬¡ã
ã«å®è¡ãããäŸåæäœã®ã°ã©ãã«ããããšã§ãããããã®äž¡æ¹ã®ã±ãŒã¹ãæ€èšããŸãããã¿ãŒã³1.ç¬ç«ããæäœã®ã°ã«ãŒããšé£æºãã
ã³ãŒããäžã«é
眮ãããŠããCancellationGroup.playgroundäžã®Githubãåã®ã»ã¯ã·ã§ã³ã§ç€ºããæäœãšåãçµæãåŸãããããã«ã¿ã¹ã¯ãèšå®ArraySumOperationããŸããããã®æäœã¯ã¿ãã«ã®é
åãåãåãã(Int, Int)ã¹ããŒå ç®é¢æ°ã䜿çšãslowAdd()ãŠãã¿ãã«ãæ§æããæ°å€ã®åèšã®é
åãäœæããŸããå
¥åé
åã®ã³ã³ããŒãã³ãã®ãµã€ã¯ã«ã¯å
éšã«é ãããŠãArraySumOperationãŸããåå¥ã®éåžžã«åçŽãªåæäœã®ã°ã«ãŒããäœæããŸãããSumOperationãæäœã¯ãSumOperationå
¥åãã¢ã®2ã€ã®æ°å€ã远å ãinputPairãäœéå ç®æ©èœãçµç±ããŠslowAdd()ãçµæãè¿ããŸãoutputïŒ
æ®éã®ã¯ã©ã¹ãäœæGroupAdd管çprivateéå¶ã®ãã¥ãŒqueueãšäžé£ã®æäœãSumOperationå
¥åé
åã®ãã¹ãŠã®ãã¢ã®åèšãèšç®ããåºåé
åã«outputArrayã¿ãã«ãé
眮ããããã«ïŒInt, Int, Int )ãœãŒã¹ããŒã¿ãšçµæã§æ§æãã
ãŸãïŒã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãåæåãããšããæ°å€GroupAddã®inputãã¢ã®å
¥åé
åã圢æãããããããåã®æŒç®ã圢æããSumOperationãŸããcompletionBlockåæŒç®ã§ãçµæãåºåã«è¿œå ãããŸãã¢ã¬ã€ã®outputArrayåäžäžã§å®è¡ãããprivateã·ãªã¢ã«ã©ã€ã³æäœappendOperationãé¿ããããã«ç«¶åç¶æ
ããã¯ã©ã¹ã¯ããã¹ãŠã®äžè¬çãªæäœãããOperationã¡ãœãããïŒstart()ãcancel ()ãwait ()ããç§ãã¡ã¯ããè€éãªæäœããšããŠãããèããããšãã§ããããã«äœæããŸããEQ emplyarã¯ã©ã¹GroupAddæ°å€ã®ãã¢ã®é
åãå
¥åã«éããŸãïŒ
startãå®è¡ãgroupAddã1ç§åŸ
æ©ããŠcancel ()ãããã¡ãœããã䜿çšããŠãã¹ãŠã®å ç®æäœãæäœãã¥ãŒããåé€ããŸããçµæãšããŠããã¹ãŠã®åäœïŒäœ¿çšã®å®äºåŸwait()ã«äœ¿çšããããšãã§ããªãmain queueããäžã«ããããšãã§ããPlaygroundïŒãæã
ã¯ãåºåé
åãççž®ïŒ
çµæã¯ãäžã§é²èЧããããšãå¯èœPlayground CancelletionGroup.playgroundã§ã®Githubããã¿ãŒã³2.äŸåããæäœã®ã°ã«ãŒããšé£æºãã
ã³ãŒããäžã«é
眮ãããŠããCancellationFourImages.playgroundäžã®GithubãäŸåããæäœã®ã°ã«ãŒããšããŠãæ¢ã«ããç¥ãããŠããçžäºæ¥ç¶ãããæäœã®ã°ã«ãŒããèããŠã¿ãŸãããUIããããã¯ãŒã¯ããã®ã€ã¡ãŒãžã®èªã¿èŸŒã¿ããã£ã«ã¿ãªã³ã°ã倿Žã§ããã¯ã©ã¹ã§ã·ãŒã±ã³ã¹ã䞊ã¹ãããã«ããŠãã ããImageProviderã«ãããã®æäœã管çããŸãOperationQueueã¡ãœããã䜿çšããŠstart ()ãwait ()ãšcancel ()ã2ã€ã®æœè±¡æäœïŒã€ãŸããã¡ãœããå®è£
ãæããªãæäœmain()ïŒããããŸãã 1ã€ã¯ãã§ã«æ
£ã芪ããã§ããASYNCHRONOUSæäœã§ããããã1ã€ã¯äŸåé¢ä¿ããå
¥åã€ã¡ãŒãžAsyncOperationãImageTakeOperationæœåºããæäœã§ããã«åºã¥ããŠinputImagedependeciesAsyncOperationæå®ãããURLã®ããããã¯ãŒã¯ãããç»åãããŠã³ããŒãããæäœãäœæããŸãããã
ãã®æäœImagePassã¯ãåä¿¡ããç»åoutputImageãæäœã®ãã§ãŒã³ã«æ²¿ã£ãŠããã«éä¿¡ããããã®ãããã³ã«ã確èªããŸããæœè±¡æäœã¯ããã®æäœã®åæåäžã«æå®ãããŠããªãå ŽåãäŸåé¢ä¿ããImageTakeOperationå
¥åã€ã¡ãŒãžinputImageãæœåºããã·ãŒã±ã³ã·ã£ã«æäœã®ãã§ãŒã³ã§ã€ã¡ãŒãžã転éããããã«äœ¿çšãããdependeciesæ¢ç¥ã®ãããã³ã«ã䜿çšããŠåºåã€ã¡ãŒãžããããã¯ã¢ãããã§ããŸãImagePassïŒ
æœè±¡ã¯ã©ã¹ImageTakeOperationãsuperclassæäœãšããŠäœ¿çšãããšéåžžã«äŸ¿å©ã§ãäŸåæäœã®ãã§ãŒã³ã«é¢äžããŸããããšãã°ããã£ã«ã¿ãŒæäœã®å ŽåFilterïŒ
ãŸãã¯ãããããã¹ã¿ãŒãã¹ã¿ã€ã«ã§ç»åãããšãŒãžã³ã°ãããæäœã®å ŽåPostProcessImageOperationïŒ
ãŸãã¯ãã¯ããŒãžã£ãŒã䜿çšããŠç°å¢ã«å
¥åç»åããæšãŠããæäœã®å ŽåImageOutputOperationïŒ
ã¯ã©ã¹ãèŠãŠã¿ãŸãããImageProviderãéåžžã®ã¯ã©ã¹ãäœæããŠImageProviderå¶åŸ¡ããããšãprivateãã¥ãŒæäœoperationQueueãããã³äžé£ã®æäœdataLoadãfilterããã³outputäžããããããç»åãããŒãããããã®URLããã£ã«ã¿ããããåè·¯ã«æž¡ãcompletionïŒ
ã¯ã©ã¹ã¯ImageProviderããã¹ãŠã®å
žåçãªåäœã®æã€Operationã¡ãœãããïŒstart()ãcancel ()ãwait ()ãç§ãã¡ã¯ããè€éãªæäœãšããŠããããèæ
®ããããšãã§ããŸããã4ã€ã®ã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãImageProviderã
ã€ã¡ãŒãžã®ããŒããéå§ããŸãïŒ
æäœã®å®äºãåŸ
æ©ããŠããã4ã€ã®ã€ã¡ãŒãžãååŸããŸãïŒ
ãã¹ãŠã®æäœã®ç¶ç¶æéã¯10ç§ããããã«è¶
ããŠããŸããã€ã¡ãŒãžã®ããŒããéå§ãã6ç§åŸ
ã£ãŠcancel ()ãããã¡ãœããã䜿çšããŠãã¹ãŠã®æäœãåé€ããŸãããã®çµæã1çªç®ã3çªç®ã4çªç®ã®3ã€ã®ç»åã®ã¿ãããŠã³ããŒããããŸã
ãçµæã¯Githubã®ãã¬ã€ã°ã©ãŠã³ãCancelletionFourImages.playgroundã§è¡šç€ºã§ããŸãããã¿ãŒã³3. TableViewControllerãšCollectionViewControllerã®æäœ
ãããžã§ã¯ãã³ãŒãã¯Githubã®ãã©ã«ããŒOperationTableViewControllerã«ãããŸããå€ãã®å ŽåãiOSã¢ããªã±ãŒã·ã§ã³ã®ããŒãã«ã«ã¯ç»åãå«ãŸããŠããããã®ç»åãåä¿¡ããã«ã¯ãµãŒããŒãžã®ã¢ã¯ã»ã¹ãå¿
èŠã§ãããŸããåã®ã»ã¯ã·ã§ã³ã§èª¬æããããã£ã«ã¿ãªã³ã°ããªã©ã®åä¿¡ç»åã«å¯Ÿãã远å ã¢ã¯ã·ã§ã³ãå«ãŸããå ŽåããããŸããããã«ã¯ããªãã®æéãããããããŒãã«ãã¹ã ãŒãºã«ã¹ã¯ããŒã«ããã«ã¯ãç»åã䜿çšãããã¹ãŠã®æäœãå€éšã§éåæã«å®è¡ããå¿
èŠããããŸããåã®ã»ã¯ã·ã§ã³ã§ç€ºããã¯ã©ã¹ã®ã¢ããªã±ãŒã·ã§ã³ãèŠãŠã¿ãŸããããããã¯ããããã¯ãŒã¯ããã€ã¡ãŒãžãããŒãããããããã£ã«ã¿ãªã³ã°ããã³å€æŽããããã®çžäºæ¥ç¶ãããæäœã®ã°ã«ãŒãã«ãã§ã«éŠŽæã¿ã®ããããšãå®è¡ããŸããäŸãšããŠã1ã€ã ãã§æ§æãããéåžžã«åçŽãªã¢ããªã±ãŒã·ã§ã³ãèããŸãmain queueImageProviderUIImage Table View ControllerãããŒãã«ã»ã«ã¯ãã€ã³ã¿ãŒãããããããŠã³ããŒããããã€ã¡ãŒãžãšããŒãããã»ã¹ãç€ºãæŽ»åã®ææšãå«ãŸããŠããã©ã®ïŒ
ãã¡ãã®ã¯ã©ã¹ã§ããImageTableViewControllerã¹ã¯ãªãŒã³ã®ãµãŒãã¹ãã©ã°ã¡ã³ãImage Table View ControllerïŒ
ã¯ã©ã¹ã®ã¢ãã«ã¯ImageTableViewController8ã€ã®é
åã§ãã®URLãïŒ- ãšããã§ã«å¡
- ãŽã§ããã£ã¢-ä»ã®ãã®ãããã¯ããã«é·ãããŒãããã³ãã£ã«ã¿ãªã³ã°
- ã¹ã³ããã©ã³ãã®å
- 忥µ-02
- ãšããã§ã«å¡
- 忥µå-16
- 忥µ-15
- 忥µ-12

ImageTableViewCellç»åãããŒããããããŒãã«ã®ã»ã«ã®ã¯ã©ã¹ã¯æ¬¡ã®ãšããã§ãã
Public APIãã®ã¯ã©ã¹ã¯ãç»åã®URLã¢ãã¬ã¹ãimageURLStringå«ãæååã§ããããããçãããªãããã«èšå®ãããšãç»åã®ããŒãã¯è¡ãããããå転ãã€ãŒã«ãã®åœ¢ã®ã€ã³ãžã±ãŒã¿ã®ã¿ãæ©èœãå§ããŸãããã ããæ¢ã«äœããã®æ¹æ³ã§ããŒãããã³åŠçãããã€ã¡ãŒãžããããmethodãåŒã³åºããŠããå Žåãã©ã€ãã¢ãã¡ãŒã·ã§ã³ã䜿çšããŠç»é¢äžã®ãã®ã»ã«ã«è¡šç€ºããŸãããã®ã¯ã©ã¹ã«ã¯ãã¡ãœããã«å€ãå²ãåœãŠããšéå§ããã¢ã¯ãã£ããã£ã€ã³ãžã±ãŒã¿ããããŸããç»åã¯ãã»ã«ãšããŒãã«ã®çžäºäœçšãæ
åœããããªã²ãŒãã¡ãœããã«ããŒããããŸããimageURLStringnilimageupdateImageViewWithImagespinnerimageURLStringtableView( _ : cellForRowAt:)UITableViewDelegateUITableViewCellUITableView ïŒ- â
tableView( _ : cellForRowAt:) , - â
tableView( _ : willDisplay:forRowAt:) , - â
tableView( _ : didEndDisplaying:forRowAt:) ,
ãã®ã¡ãœãããå¯èœãªéããä¿é²ãããããã«ãã¯ã©ã¹ImageProviderã䜿çšããéåæã€ã¡ãŒãžã®èªã¿èŸŒã¿ã®èŠæ±ã¯ã¡ãœããã®ç¯å²å€ã«ãªããŸãtableView( _ : cellForRowAt:)ãtableView( _ : willDisplay:forRowAt:)ããªã²ãŒãã¡ãœããã«é
眮ãããã»ã«ã衚瀺ãããããã«æºåããŸããå¥ã®tableView( _ : didEndDisplaying:forRowAt:)ããªã²ãŒãã¡ãœããã¯ãã»ã«ãç»é¢ãé¢ãããŸã§ã«å®äºããªãã€ã¡ãŒãžã®ããŠã³ããŒãèŠæ±ãç Žæ£ããããã«äœ¿çšãããŸããããã¯ããªãäžè¬çãªã¢ãããŒãã§ãããåäœããã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšã§ããŸãTableViewãããã«ãããããŒãã«ã®ã¹ã¯ããŒã«ããã©ãŒãã³ã¹ãåäžããŸããããããæåã«ãImageProviderãã®ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããã¯ã©ã¹ã«æ»ããŸããImageProvideråã®ã»ã¯ã·ã§ã³ã§äœ¿çšãããã¯ã©ã¹ããªã¢ã³ããšã¯å¯Ÿç
§çã«Playgroundãç°¡ç¥åããã圢åŒã䜿çšããŸããã€ãŸããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãåæåãããšãImageProviderãisSuspended = trueæäœãã¥ãŒïŒïŒã忢ããŠããImageProviderãã¡ãœããã䜿çšããŠã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ãå
·äœçã«éå§ããå¿
èŠã¯ãããŸãããstart()åæåäžã«äŸåæäœã®ãã§ãŒã³ãããã«éå§ããwaitUntilFinishedçããèšå®ããŸããfalseããã¯Playgroundã¢ããªã±ãŒã·ã§ã³ã§ã¯ãªããåæã¡ãœããã䜿çšããŸãwait()ã
ãããã£ãŠãã¯ã©ã¹ImageProviderã«ã¯ã€ãã·ã£ã©ã€ã¶ãããããã®å
¥åã«ãç»åimageURLStringã®URLãšã¯ã©ã¹ã®ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæãã人ã«åã®ç»åcompletionãgenericè¿ãClosure ãå«ãæååãæå®ããå¿
èŠããããŸãUIImage?ImageProviderãèšç®ãããããããã£ã䜿çšãã代ããã«imageãå
¥ååè·¯completionã«ã¯çœ²åããããŸã(UIImage?) -> ()ãã€ãŸããç»åUIImage?ãååŸããäœãè¿ããŸãããã«æ»ãããã«äœ¿çšã§ããŸãUITableViewControllerãããã«ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã®ç Žæ£ãèš±å¯ããå¿
èŠããããŸããããã«ãããImageProviderãã¹ãŠã®æäœãå®äºããåã«ããŒãã«ã»ã«ãç»é¢ãé¢ãããšãéå§ããããã¹ãŠã®æäœãç Žæ£ãããŸãããããã£ãŠãcancel()ã¯ã©ã¹ã«ã¡ãœãããããImageProviderãŸãããã®ããããã®ã¯ã©ã¹ImageProviderã¯ããµãŒããŒããã®ã€ã¡ãŒãžã®ããŒãããã£ã«ã¿ãªã³ã°ãããã³ã¡ãœãããžã®é
ä¿¡ã«é¢ããäŸåæäœã®ã°ã«ãŒãã®éåæå®è¡ãæäŸããŸãUITableViewDelegateãå¿
èŠã«å¿ããŠããã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãåé€ã§ããŸããã«æ»ãImageTableViewControllerãã¡ãœããtableView( _ tableView:, cellForRowAt indexPath:)ã«ç»åãããŒããã代ããã«ãå¥ã®ããªã²ãŒãã¡ãœããtableView( _ tableView: , willDisplay cell:, forRowAt indexPath:)ã§ãããè¡ããŸã- ãããŠãã¡ãœããã®ç»åãåé€ããŸãtableView( _ tableView: , didEndDisplaying cell:, forRowAt indexPath:)ãããã2ã€ã®ã¡ãœããã®æ¡åŒµæ©èœextensionãäœæããŸããããã¡ãœããããå§ããŸãããtableView( _ tableView: , willDisplay cell:, forRowAt indexPath:)ã
ã¡ãœããã®tableView( _ tableView:, cellForRowAt indexPath:)ããã«ãã»ã«cellãšindexPathããŸããæšæºã®æé ã«åŸã£ãŠãã»ã«ã®ã¿ã€ããã§ããããšã確èªãImageTableViewCellãŸããæ¬¡ã«ãç»åã®URLãšããŠã®imageProvideræååimageURLs [ (indexPath as NSIndexPath).row ]ãšããããŒã«ãã¯ããŒãžã£ãŒãšããŠèšèšãããã¯ããŒãžã£ãŒãäœæããŸããã¯ããŒãžã£ãŒã§ã¯ããã®ããŒãã«ã»ã«ã«è¡šç€ºããå¿
èŠãããç»åãååŸããŸããããã¯ãæŽæ°ã«äœ¿çšããå¿
èŠããããŸãimageUImain queueãªããªãUIãããã¯ã°ã©ãŠã³ããã¥ãŒïŒbackground queueïŒã§æŽæ°ãè¡ãããšãããšãããã¯æ©èœããããªããã®ç»åã衚瀺ãããªãã®ãäžæè°ã«æãããã§ããmainã¯ã©ã¹ããããã£ããããŸãOperationQueueãmain queueãå¿
èŠãªã»ã«ãæŽæ°ããã¡ãœããupdateImageViewWithImage( image )ãåŒã³åºãmain queueã ãUITableViewCellã§ããããã§ãæäœã®åé€ã®å¯èœæ§ã«ã€ããŠèããå¿
èŠããããŸãããããè¡ãã«ã¯ãäœæããããã®ãžã®ãªã³ã¯ã倱ãå¿
èŠã¯ãããŸããimageProviderãããããªããšãåŸã§ãããèŠã€ããŠãããã«é¢é£ä»ããããŠããæäœãåé€ã§ããŸãããç§ãã¡ã¯ãã¯ã©ã¹ã®å
é ã«ç§»åImageTableViewControllerããCãšããååã®æ°ããããããã£ã远å imageProvidersïŒ
ããããã£ã¯ãimageProvidersåã®ãªããžã§ã¯ãã®éåã§ããimageProviderãæåã¯ç©ºã§ããImageProvider.swiftãã¡ã€ã«ã®äžéšãèŠãŠã¿ãŸããããããªãã¯ãæ¢åã®æ¡åŒµãã§ã«ããã«ããã§ãããextensionã¯ã©ã¹ImageProviderãããã³ã«ã確èªããHashableã»ããã«å¿
èŠãªã®SetïŒ
ç§ãã¡ã¯ãèšç®ããããã£ãååŸhashValueãšå¹³çã®ããã®æ¯èŒæŒç®åã==ãããã§ããªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãã€ã³ã¹ããŒã«ããŠæ¯èŒã§ããŸãImageProviderãã«æ»ãImageTableViewControllerãããã§ããªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ã远跡ImageProviderããimageProvidersçŸåšã¢ã¯ãã£ããªã»ããã«ãããã远å ã§ããŸãã
ãã®ã³ãŒããèŠãŠãäœãèµ·ãã£ãŠããããæ®µéçã«ç¢ºèªããŠã¿ãŸããããããã¯ããªã²ãŒãã¡ãœããã§ãtableViewãã»ã«ãç»é¢ã«è¡šç€ºãããçŽåã«åŒã³åºãããŸãããã®æç¹ã§ãImageProvideréåæçã«èªã¿èŸŒã¿ãç»åããã£ã«ã¿ãªã³ã°ããçµæã®ç»åimageãã«è¿ããã®ãäœæãcompletionHandlerãŸããã®imageæŽæ°UIImageViewã«äœ¿çšãmain queueãŸãããã®åŸãåŸã§ç Žå£ã§ããããImageProviderã«ã倿°ã§èšæ¶ãimageProvidersãŸããããã¯ã次ã®ããªã²ãŒãã¡ãœããtableViewã§tableView( _ tableView:, didEndDisplaying cell:, forRowAt indexPath:)ãã»ã«ãç»é¢ãé¢ããçŽåŸã«åŒã³åºãããååã§è¡ããŸããããã¯ç§ãã¡ããã®ãã¹ãŠã®æäœãç Žå£ããå¿
èŠãããããšãããã«ããImageProviderïŒ
ãããè¡ãã«ã¯ãç§ãã¡ãèŠã€ãImageProviderã»ã«çšcellåã³æ¹æ³ã䜿çšcancel ()ããã«ImageProviderããã®ãããã€ããŒã®ãã¹ãŠã®æäœãåé€ããŠããããããã€ããŒèªäœãsetããåé€ããŸãimageProvidersããã€ãã®ããã«ãæåã«æšæºæé ãå®è¡ããŠãã»ã«ã®ã¿ã€ããã§ããããšã確èªããŠããããã®ã»ã«ImageTableViewCellãšåãè¡ãæã€ãã¹ãŠã®ãããã€ããŒãèŠã€ããŸãImageURLStringãããããã¹ãŠã®ãããã€ããŒã調ã¹ãŠåé€ããã»ããããåé€ããŸãimageProvidersããããç§ãã¡ãããå¿
èŠããããã¹ãŠã§ããã¢ããªã±ãŒã·ã§ã³ãå®è¡ããŸãããã
ç»åã®èªã¿èŸŒã¿äžã«ã¢ã¯ãã£ããã£ã€ã³ãžã±ãŒã¿ãåäœããã¹ã¯ããŒã«ãé
å»¶ãªãéåžžã«é«éã«åäœããããã«ãªããŸãããç»åã¯ããŒãããããŸã§ç©ºã§ãã¢ãã¡ãŒã·ã§ã³åãããŸããçŽ æŽãããã
ãããžã§ã¯ãã³ãŒãã¯Githubã®ãã©ã«ããŒOperationTableViewControllerã«ãããŸããOperation OperationQueue GCD
GCDãããŠOperationsã圌ããã©ã®ããã«ç°ãªãããã衚ã·ã§ãŒã§ã¯ã䌌ããããªæ©èœã®å€ããæã£ãŠããŸãã
DispatchGroupãããŠãOperationQueueãããã¯ãã¹ãŠã®ã¿ã¹ã¯ã®å®å
šãªå®äºã«é¢é£ããã€ãã³ããåŠçã§ããŸããwaitUntilAllOperationsAreFinishedããã¥ãŒã®ã¡ãœãããéå§ãããšãã¯éåžžã«æ³šæããå¿
èŠãããOperationQueueãŸãmain queueãäŸåé¢ä¿ïŒdependeciesïŒã«é¢ããŠGCDã¯ãã¿ã¹ã¯ã®ãã§ãŒã³ãprivateé æ¬¡ïŒserialïŒã«å®è£
ããã ãDispatchQueueã§ããããããããã¯æã匷ãåŽé¢OperationQueueã§ããäŸåé¢ä¿ïŒdependeciesïŒOperationQueueã¯åãªããã§ãŒã³ãããè€éã«ãªãå¯èœæ§ããããç°ãªããã¥ãŒã§æäœãå®è¡ã§ããŸãOperationQueueãã§ããªã¢ã䜿çšã§ããŸãGCDã·ãŒã±ã³ã·ã£ã«ïŒserialïŒãã¥ãŒãDispatchQueueé©åã§ãªãå Žåã®ãã©ã€ã¿ãŒããšããªãŒããŒãã®åé¡ã解決ãããã䜿çšããŠãã®åé¡ã解決ããé©åãªæ¹æ³ã¯OperationQueueéåžžã«çŽãããããflagséåžžã«ç¹å¥ãªäŸåé¢ä¿ãå¿
èŠã§ããã§GCDã®ã¿åé€ã§ãDispatchWorkItemsãŸããOperationsç¬èªã®ã¡ãœããã䜿çšããŠæäœãåé€ããããšãcancel()ããã¹ãŠã®æäœãããã«åé€ããããšãã§ããŸãOperationQueueãã§ç絡ãåé€ã§ãBlockOperationãŸãããšã®äž¡æ¹GCDã§OperationsãSYNCHRONOUSæ©èœãéåæçã«å®è¡ã§ããŸããããããããšã§ããã®æäœOperationã¯ãå®è£
ãå«ãããã®åå©çšå¯èœãªæ©èœã®ãã¹ãŠã®ããŒã¿ãã«ãã»ã«åããããã®ãªããžã§ã¯ãæåã¢ãã«ãæäŸããŸãsubclasses Operationãããããå€ãã®å Žåãè€éãªäŸåé¢ä¿ãæããªãåçŽãªã¿ã¹ã¯ã®å Žåã¯GCDãæäœãäœæãããããã軜ããã¡ãœããã䜿çšããæ¹ã䟿å©Operationã§ããããã«ãDispatchãããã¯ã®GCDå®äºã«èŠããæéã¯ãããç§ããããªç§ãŸã§ã§ãOperationéåžžã¯æ°ããªç§ããæ°åããããŸãããããã«
ãã®èšäºã§ã¯ãæäœã«é¢ãã以äžã®è³ªåãèæ
®ããOperationãã€ãã¥ãŒæäœOperationQueueïŒ
1.æäœãOperationåé¡ãšãã©ã€ããµã€ã¯ã«ããšãã®ã¹ããŒã¿ã¹ã衚瀺ããããããã£ãæã€1ã€ã®ãªããžã§ã¯ãå
ã®ããŒã¿ãã«ãã»ã«åããããšãã§ããŸãã2. BlockOperationãªããžã§ã¯ãæåã®ãã©ãããŒãDispatchQueue.global()ã§ããããã®ã°ã«ãŒãã®å¶åŸ¡ã倱ãã®ã§ã¯ãªããã¯ããŒãžã£ãŒã®ã°ã«ãŒãã®å®è¡ã远跡ã§ããŸãDispatchQueue.global()ããã§ã«ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšããŠããŠããããã«å¹²æžããããªãå Žåã¯BlockOperationã代æ¿ãšããŠåçŽãªæäœã«äœ¿çšãããšäŸ¿å©ã§ãã3.éçšãéå§ããããšããã®äž»ãªå¯èœæ§ãæããã«ãªããŸãGCDOperationsDispatchQueueOperationOperationQueueãæäœãæºåãããOperationããããOperationQueueã«æž¡ããŸããããã¯ããã¹ãŠã®æäœã®å®è¡é åºãå¶åŸ¡ããŸããããã¯ãæ¬è³ªçã«éåžžã«åçŽãªã¢ãã«ã§ããããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®è€éããé ããŸããOperationQueueã«äŒŒãŠDispatchGroupãããç°ãªãã¬ãã«ã®æäœãçµã¿åãããŠqualityOfServiceããã¹ãŠã®æäœãå®äºãããŸã§åŸ
ã€ããšãã§ããŸãããã ãããã®syncã¡ãœãããåŒã³åºããšãã¯éåžžã«æ³šæããå¿
èŠããããŸãã4.æäœã«ASYNCHRON颿°ãå«ããã«ã¯Operationããã®å®äºãæ£ç¢ºã«èšé²ããããã«ç¹å¥ãªããšãããå¿
èŠããããŸããKVOAsyncOperationã䜿çšããŠASYNCHRONæäœãæåã§ç®¡çããå¿
èŠããããŸãã5.æ¯é¡ã®ãªãæäœOperationããããäžé£ã®æäœã«çµã¿åãããŠãè€éãªäŸåé¢ä¿ã°ã©ãïŒdependenciesïŒãäœæã§ãããšããããšã§ããããã¯ãOperation1ã€ä»¥äžã®ä»ã®æäœOperationãå®äºãããŸã§éå§ã§ããªãæäœãéåžžã«ç°¡åã«èå¥ã§ããããšãæå³ããŸãããã®èšäºã§ã¯ããããã³ã«protocolã䜿çšãOperationãŠãäŸåé¢ä¿ã°ã©ãïŒdependenciesïŒã®æäœéã§ããŒã¿ã転éããæ¹æ³ã瀺ããŸãããã ãdeadLockãç¹ã«ç°ãªãæäœã®æäœéã«äŸåé¢ä¿ãããå Žåã¯ã解決ã§ããªããããããã¯ãåŒãèµ·ããå¯èœæ§ã®ãããµã€ã¯ã«ãåé¿ããããã«ãäŸåé¢ä¿ã°ã©ãã調æ»ããå¿
èŠããããŸãOperationQueueã6.æäœOperationãæäœãã¥ãŒã«è»¢éãããOperationQueueãã¿ãŒã³OperationQueueèªäœãå®è¡ã®ããã®æäœãéå§ããããã®ã¹ã±ãžã¥ãŒã«ãäœæãããã®å®è¡ãå¶åŸ¡ããããããã®æäœã®å¶åŸ¡ã倱ããŸãããã ããã¡ãœããcancel ()ã䜿çšããŠãæäœãéå§ãããªãããã«ããããšãã§ããŸãããã®èšäºã§ã¯isCancelledãæäœã®æ§ç¯æã«ããããã£ãèæ
®ããOperationæ¹æ³ãšãæäœãã¥ãŒã®ãã¹ãŠã®æäœãå®å
šã«åé€ããæ¹æ³ã瀺ããŸãOperationQueueã7.çµè«ã¯ãã€ã³ã¿ãŒãããããååŸããç»åã§ããŒãã«ãã¹ã¯ããŒã«ããå¿
èŠããããããã£ã«ã¿ãªã³ã°ããããšãŒãžã³ã°ããªã©ã®è¿œå ã¢ã¯ã·ã§ã³ãå¿
èŠãªå Žåã®å®éã®ã·ããªãªãåæ ããã¢ããªã±ãŒã·ã§ã³ã®éçºã瀺ããŠããŸããããã«ã¯ããªãã®æéãããããããŒãã«ãã¹ã ãŒãºã«ã¹ã¯ããŒã«ããã«ã¯ãç»åã䜿çšãããã¹ãŠã®æäœãå€éšã§éåæã«å®è¡ããå¿
èŠããããŸãmain queueããã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãæäœOperationãç¹ã«éåææäœAsyncOperationãšãã®äŸåé¢ä¿ïŒdependenciesïŒãæäœããããã®å¹
åºãæè¡ã䜿çšããŸãããããã«ããã倧å¹
ãªæ¹åãéæããããšãã§ããŸããUIãäžç·ã«ãã®èšäºã§ã以åã®ã®ãããªãã®äžã«ãã«ãã¹ã¬ããåŠçã®å
šäœåSwift 3ãš4ä»ååšããŠããiOSã®äžããå®å®æ§ïŒïŒã«å ããŠããã«ãã¹ã¬ãããSwiftããŒãžã§ã³ã®Swift 5åªå
é äœABIãšããŠå®£èšãããŠããå ŽåãçŸåšæ·èšãããŠãããã«ãã¹ã¬ããåŠçã®å°æ¥ã®å¯èœæ§ã®è°è«ã«å
šé¢çã«åå ã§ããŸãconcurrencyãããŒãžã§ã³Swift 5å®å
šã«æ°ãããã«ãã¹ã¬ããã¢ãã«ã®äœæ¥ã®éå§ã®ã¿ãå«ãŸãããã®å®è£
ã¯å°æ¥ã®ããŒãžã§ã³ã§ãç¶ç¶ãããŸããSwift 5ã«ã¯ãå°æ¥ã®ãã«ãã¹ã¬ããã¢ãã«ã®ææ¡ãæ¢ã«ãããŸããã ãããã¢ãŒã¿ãŒãã€ããïŒããããŠè¡ã£ãŠãã ãããSwiftã®é²åã¯ããã§èŠãããšãã§ããŸããåç
§è³æ
â WWDC2015ãé«åºŠãªNSOperationsïŒã»ãã·ã§ã³226ïŒãâ iOSã®NSOperationsããæ¥œãã¿ãã ããâ Swiftã®NSOperationãšNSOperationQueueã®ãã¥ãŒããªã¢ã«â GCDãšOperationsã®iOSåæå®è¡æ§â IOSã® äžŠè¡æ§â Swiftã®åæå®è¡æ§ïŒ1ã€ã®å¯èœãªã¢ãããŒã