iOSã®
ãã«ãã¹ã¬ãã ïŒåæå®è¡ïŒã¯
ãiOSã¢ããªã±ãŒã·ã§ã³éçºè
ãžã®ã€ã³ã¿ãã¥ãŒäžã«å°ãããã質åãããã³
iOSã¢ããªã±ãŒã·ã§ã³ãéçºããéã«ããã°ã©ããŒã
ç¯ãæå€§ã®ééãã«åžžã«å«ãŸããŠãããšèšããªããã°ãªããŸããã ãããã£ãŠããã®ããŒã«ãå®å
šã«ãã¹ã¿ãŒããããšãéåžžã«éèŠã§ãã
ãããã£ãŠãã¢ããªã±ãŒã·ã§ã³ãããã
main threadã§å®è¡ãããŸãã
main threadã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒ
UI ïŒã衚瀺ããã³ãŒããå®è¡ããŸãã ãããã¯ãŒã¯ããããŒã¿ãããŠã³ããŒããããã
main thread ïŒã¡ã€ã³ã¹ã¬ããïŒã§ç»åãåŠçãããªã©ãã¢ããªã±ãŒã·ã§ã³ã«ãæéã®ããããã³ãŒãã远å ãå§ãããšããã«ã
UIã®åäœã倧å¹
ã«é
ããªããå®å
šãªãããªãŒãºãã«è³ãããšãããããŸãã
ãã®ãããªåé¡ãçºçããªãããã«ãã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ã倿Žããã«ã¯ã©ãããã°ããã§ããïŒ ãã®å Žåããã«ãã¹ã¬ããïŒ
oncurrency ïŒãå©ããšãªãã2ã€ä»¥äžã®ç¬ç«ããã¿ã¹ã¯ïŒ
tasks ïŒãåæã«å®è¡ã§ããŸãïŒèšç®ããããã¯ãŒã¯ãŸãã¯ãã£ã¹ã¯ããã®ããŒã¿ã®ããŠã³ããŒããç»ååŠçãªã©ã
ä»»æã®æç¹ã§ããã»ããµãã¿ã¹ã¯ã®1ã€ãå®è¡ã§ãã察å¿ããã¹ã¬ãããããã«å²ãåœãŠãããŸãã
ã·ã³ã°ã«ã³ã¢ããã»ããµïŒiPhoneããã³iPadïŒã®å Žåãã¿ã¹ã¯ãå®è¡ããããã¹ã¬ãããéã®è€æ°ã®çæã¹ã€ããã«ãã£ãŠãã«ãã¹ã¬ããïŒ
oncurrency ïŒãå®çŸãããã·ã³ã°ã«ã³ã¢ããã»ããµã§ã®ã¿ã¹ã¯ã®åæå®è¡ã®ä¿¡é Œæ§ã®é«ãã¢ã€ãã¢ãäœæãããŸãã ãã«ãã³ã¢ããã»ããµïŒMacïŒã§ã¯ãã¿ã¹ã¯ã«é¢é£ä»ããããåãã¹ã¬ãããã«ãã¿ã¹ã¯ãå®è¡ããããã®ç¬èªã®ã«ãŒãã«ãæäŸããããšããäºå®ã«ãã£ãŠããã«ãã¹ã¬ãããå®çŸãããŸãã ãããã®æè¡ã¯ã©ã¡ããããã«ãã¹ã¬ããïŒ
oncurrency ïŒã®äžè¬çãªæŠå¿µã䜿çšããŠããŸãã
ã¢ããªã±ãŒã·ã§ã³ã«ãã«ãã¹ã¬ãããå°å
¥ããããšã«å¯Ÿããäžçš®ã®æ¯æãã¯ãããŸããŸãªã¹ã¬ããã§å®å
šãªã³ãŒãå®è¡ã確ä¿ããããšãé£ããããšã§ãïŒ
thread safety ïŒã ã¿ã¹ã¯ïŒ
tasks ïŒã䞊è¡ããŠåäœããããšããã«ãç°ãªãã¿ã¹ã¯ïŒ
tasks ïŒãåããªãœãŒã¹ã«ã¢ã¯ã»ã¹ããããããšãã°ç°ãªãã¹ã¬ããã®åã倿°ã倿ŽãããããŸãã¯ååŸããããšããäºå®ã«é¢é£ããåé¡ããããŸãä»ã®ã¿ã¹ã¯ã«ãã£ãŠãã§ã«ãããã¯ãããŠãããªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ã ããã«ãããä»ã®ã¹ã¬ããã®ã¿ã¹ã¯ã«ãã£ãŠäœ¿çšãããŠãããªãœãŒã¹èªäœãç Žå£ãããå¯èœæ§ããããŸãã
iOSããã°ã©ãã³ã°ã§ã¯ã
ã¹ã¬ãã ã
Grand Central Dispatch ïŒç¥ããŠGCDïŒãããã³
æäœãšããè€æ°ã®ããŒã«ã®åœ¢åŒã§éçºè
ã«ãã«ãã¹ã¬ãããæäŸããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®çç£æ§ãšå¿çæ§ãåäžãããããã«äœ¿çšãããŸãã ããã¯äœã¬ãã«ã®ã¡ã«ããºã ã§ããããã
Threadã¯èæ
®ããŸãããããã®èšäºã§ã¯
GCDã«çŠç¹ãåœãŠãå°æ¥ã®åºçç©ã§ã¯
Operation ïŒ
GCDäžã«æ§ç¯ããããªããžã§ã¯ãæå
API ïŒã«çŠç¹ââãåœãŠ
API ã
Swift 3ãç»å Žããåã¯ã
Grand Central Dispatch (GCD ïŒãªã©ã®åŒ·åãªãã¬ãŒã ã¯ãŒã¯ã«ã¯CããŒã¹ã®
APIããããŸããããããã¯äžèŠéæ³ã®ããã«æããŸããã¿ã¹ã¯ã
Swift 3ãã¹ãŠãåçã«å€åããŸããã
GCDã¯ãéåžžã«äœ¿ããããæ°ããå®å
šã«
Swiftæ§æãåãåããŸããã å€ã
API GCDã«å°ãã§ã粟éããŠããã°ããŸã£ããæ°ããæ§æã¯ç°¡åã«çè§£ã§ããŸãã ããã§ãªãå Žåã¯ãå¥ã®éåžžã®
iOSããã°ã©ãã³ã°ã»ã¯ã·ã§ã³ãå匷ããå¿
èŠããããŸãã æ°ãã
GCDãã¬ãŒã ã¯ãŒã¯ã¯ããã¹ãŠã®
iOSããã€ã¹ãå«ã
Apple Watchãã
Apple TVããã³
MacãŸã§ããã¹ãŠã®
Appleããã€ã¹ã®
Swift 3ã§åäœããŸãã
ãã1ã€ã®
è¯ããã¥ãŒã¹ã¯ã
Xcode 8以éã§ã¯ã
Playgroudãªã©ã®åŒ·åã§èŠèŠçãªããŒã«ã䜿çšããŠ
GCDãš
OperationãåŠç¿ã§ããããšã§ãã
Xcode 8ã¯
PlaygroudPageãšåŒã°ããæ°ãããã«ããŒã¯ã©ã¹ãå°å
¥ããŸããããã¯ã
Playgroudãç¡æéã«
Playgroudãããæ©èœãåããŠããŸãã ãã®å Žåã
DispatchQueueãã¥ãŒã¯ããžã§ããå®äºãããŸã§å®è¡ã§ããŸãã ããã¯ããããã¯ãŒã¯èŠæ±ã«ãšã£ãŠç¹ã«éèŠã§ãã
PlaygroudPageã¯ã©ã¹ã䜿çšããã«ã¯ã
PlaygroudSupportã¢ãžã¥ãŒã«ãã€ã³ããŒãããå¿
èŠããããŸãã ãã®ã¢ãžã¥ãŒã«ã䜿çšãããšã
run loopã«ã¢ã¯ã»ã¹ããã©ã€ã
UI衚瀺ãã
Playgroudéåææäœãå®è¡ããããšãã§ããŸãã 以äžã«ããã®èšå®ãå®éã«ã©ã®ããã«èŠãããã瀺ããŸãã
Xcode 8ãã®æ°ãã
Playgroundæ©èœã«ããã
Swift 3ãã«ãã¹ã¬ããåã«ã€ããŠéåžžã«ç°¡åãã€çŽæçã«åŠç¿ã§ããŸãã
concurrencyããããçè§£ããããã«ã
Appleã¯äž¡æ¹ã®ããŒã«ã
GCDãš
Operationåäœããæœè±¡çãªæŠå¿µãããã€ãå°å
¥ããŸããã åºæ¬çãªæŠå¿µã¯
queueã§ãã ãããã£ãŠã
iOSã¢ããªã±ãŒã·ã§ã³ã®éçºè
ã®èгç¹ãã
iOSãã«ãã¹ã¬ããåã«ã€ããŠè©±ããšãã¯ããã¥ãŒã«ã€ããŠè©±ããŸãã ãã¥ãŒã¯ãããšãã°æ ç»é€šãžã®ãã±ãããªã©ã人ã
ã賌å
¥ããããã«äžŠãã§ããéåžžã®ãã¥ãŒã§ããããã®å Žåãã¯ããŒãžã£ãŒã䞊ãã§ããŸãïŒ
closure -ã³ãŒãã®å¿åãããã¯ïŒã ã·ã¹ãã ã¯åã«ãã¥ãŒã«åŸã£ãŠããããå®è¡ããæ¬¡ã®ãã¥ãŒãé çªã«ãåŒãåºãããŠããã®ãã¥ãŒã«å¯Ÿå¿ããã¹ã¬ããã§å®è¡ããããã«éå§ããŸãã ãã¥ãŒã¯
FIFOãã¿ãŒã³ïŒ
FIFOåŸããŸããã€ãŸããæåã«ãã¥ãŒã«å
¥ãããã人ãæåã«å®è¡ãããŸãã å€ãã®ãã¥ãŒãæã€ããšãã§ããã·ã¹ãã ã¯åãã¥ãŒã®1ã€ãã¯ããŒãžã£ãŒã«ãåŒãåºãããããããéå§ããŠç¬èªã®ã¹ã¬ããã§å®è¡ããŸãã ããã«ããããã«ãã¹ã¬ããåãå®çŸããŸãã
ãã ããããã¯
iOS oncurrencyãã©ã®ããã«æ©èœãããã®äžè¬çãªèãæ¹ã«ãããŸããã é°è¬ã¯ããããã®ãã¥ãŒãçžäºã«é¢é£ããã¿ã¹ã¯ãå®äºãããšããæå³ã§ïŒã·ãŒã±ã³ã·ã£ã«ãŸãã¯ãã©ã¬ã«ïŒããããã®ã¿ã¹ã¯ããã¥ãŒã«é
眮ãããæ©èœïŒåæãŸãã¯éåæïŒã§ãããããã«ãã£ãŠçŸåšã®ãã¥ãŒããããã¯ãããããªããã§ãã
ã·ãªã¢ã«ïŒ serial ïŒããã³ãã©ã¬ã«ïŒ concurrent ïŒãã¥ãŒ
ãã¥ãŒã®å
é ã«ããã¿ã¹ã¯ïŒã¯ããŒãžã£ïŒãiOSã«ãã£ãŠããã«ããããå®äºãããŸã§å®è¡ãããæ¬¡ã®ã¢ã€ãã ããã¥ãŒãããã«ãããå Žåããã¥ãŒã¯ã
serial ãã«ãªããŸãã ããã¯ã
serial queueãŸãã¯ã·ãªã¢ã«ãã¥ãŒã§ãã ã·ã¹ãã ã¯ããã¥ãŒã®å
é ã«ããã¯ããŒãžã£ãŒãããã«ãããç¹å®ã®ã¹ã¬ããã§å®è¡ãéå§ãããšããã¥ãŒããc
oncurrent ãïŒãã«ãã¹ã¬ããïŒã«ã§ããŸãã ã·ã¹ãã ã«ãŸã ãªãœãŒã¹ãããå Žåããã¥ãŒããæ¬¡ã®èŠçŽ ãååŸããæåã®é¢æ°ããŸã æ©èœããŠããéã«å¥ã®ã¹ã¬ããã§å®è¡ããããã«ãããéå§ããŸãã ãããŠãã·ã¹ãã ã¯å€ãã®æ©èœãæ¡åŒµã§ããŸãã ãã«ãã¹ã¬ããã®äžè¬çãªæŠå¿µãš
"concurrent queues" ïŒãã«ãã¹ã¬ãããã¥ãŒïŒãæ··åããªãããã«ã
"concurrent queue"䞊åãã¥ãŒãšåŒã³
"concurrent queue" ããã®äžŠååŠçã®æè¡çãªå®è£
ã«å
¥ããã«ãçžäºã«é¢é£ããã¿ã¹ã¯ã®é åºãåç
§ããŸãã
serial ïŒã·ãŒã±ã³ã·ã£ã«ïŒãã¥ãŒã§ã¯ãã¯ããŒãžã£ãŒã¯å®è¡ãããé åºã§å³å¯ã«å®äºããŸããã
concurrent ïŒãã©ã¬ã«ïŒãã¥ãŒã§ã¯ããžã§ãã¯äºæž¬äžèœãªæ¹æ³ã§çµäºããŸãã ããã«ã
serialãã¥ãŒäžã®ç¹å®ã®ã¿ã¹ã¯ã°ã«ãŒãã®åèšå®è¡æéãã
concurrentãã¥ãŒäžã®åãã¿ã¹ã¯ã°ã«ãŒãã®å®è¡æéã倧å¹
ã«è¶
ããŠããããšãããããŸãã çŸåšã®
serial ïŒã·ãŒã±ã³ã·ã£ã«ïŒãã¥ãŒã§ã¯ã1ã€ã®ã¿ã¹ã¯ã®ã¿ãå®è¡ããã
concurrent ïŒãã©ã¬ã«ïŒãã¥ãŒã§ã¯ãçŸåšã®æéã®ã¿ã¹ã¯æ°ã倿Žã§ããŸãã
åæããã³éåæã®ã¿ã¹ã¯å®è¡
queueäœæããããšã
asyncçŸåšã®ãã¥ãŒã«é¢é£ããåæå®è¡ãš
asyncçŸåšã®ãã¥ãŒã«é¢é£ããéåæå®è¡ã®2ã€ã®é¢æ°ã䜿çšããŠã¿ã¹ã¯ã
queueã«é
眮ã§ããŸãã
åæ
sync颿°ã¯ãã¿ã¹ã¯ãå®äºããåŸã«ã®ã¿å¶åŸ¡ãçŸåšã®ãã¥ãŒã«è¿ããçŸåšã®ãã¥ãŒããããã¯ããŸãã
asyncæ©èœã¯ã
syncæ©èœãšã¯å¯Ÿç
§çã«ãå¥ã®ãã¥ãŒã§ãžã§ããéå§ããçŽåŸã«ãå®äºããã®ãåŸ
ããã«ãçŸåšã®ãã¥ãŒã«å¶åŸ¡ãæ»ããŸãã ãããã£ãŠã
asyncæ©èœã¯ãçŸåšã®ãã¥ãŒã§ã®ã¿ã¹ã¯ã®å®è¡ããããã¯ããŸããã
éåæå®è¡ã®å Žåãã·ãŒã±ã³ã·ã£ã«ïŒ
serial ïŒãã¥ãŒãšããŠã®ãå¥ã®ãã¥ãŒãã«ãªãããšããããŸãã
ããã³äžŠåïŒ
concurrent ïŒãã¥ãŒïŒ
éçºè
ã®ã¿ã¹ã¯ã¯ã
syncæ©èœã䜿çšããŠ
syncçã«ãŸãã¯éåææ©èœã䜿çšããŠ
asyncçã«ãã¥ãŒãéžæããã¿ã¹ã¯ïŒéåžžã¯ã¯ããŒãžã£ãŒïŒããã®ãã¥ãŒã«è¿œå ããããšã®ã¿ã§ãããã®åŸã
iOSã®ã¿ãæ©èœããŸãã
ãã®æçš¿ã®æåã«ç€ºããã¿ã¹ã¯ã«æ»ããããããã¯ãŒã¯ããã®ããŒã¿ããããã¯ãŒã¯ããå¥ã®ãã¥ãŒã«ããŒã¿ãåä¿¡ããã¿ã¹ã¯ã®å®è¡ãåãæ¿ããŸãã
å¥ã®
Dispatch Queueãããã¯ãŒã¯ãã
Dataãåä¿¡ããåŸã
Main threadéãè¿ã
Main thread ã
å¥ã®
DispatchQueueãã¥ãŒã§ãããã¯ãŒã¯ãã
Dataãåä¿¡ãããšã
Main threadã¯è§£æŸããã
UIã§çºçãããã¹ãŠã®ã€ãã³ããåŠçããŸãã ãã®å Žåã®å®éã®ã³ãŒããã©ã®ããã«èŠãããèŠãŠã¿ãŸãããïŒ

ããªãã®æéããããã
Main queueããããã¯ããå¯èœæ§ãããimageURL
imageURLãä»ããŠããŒã¿ãããŠã³ããŒãããã«ã¯ããã®ãªãœãŒã¹éäžåã¿ã¹ã¯ãã
qosã
.utilityçããã°ããŒãã«äžŠåãã¥ãŒã«
.utility ïŒè©³çްã¯åŸè¿°ïŒã
let imageURL: URL = URL(string: "http://www.planetware.com/photos-large/F/france-paris-eiffel-tower.jpg")! let queue = DispatchQueue.global(qos: .utility) queue.async{ if let data = try? Data(contentsOf: imageURL){ DispatchQueue.main.async { image.image = UIImage(data: data) print("Show image data") } print("Did download image data") } }
ããŒã¿
dataãåä¿¡ããåŸ
dataåã³
Main queueã«æ»ãããã®ããŒã¿ã
image1.imageããŠ
UIèŠçŽ
image1.imageãæŽæ°ããŸãã
Main queueãããã³ã¹ãã®ããããã¿ã¹ã¯ã®å®è¡ããè¿åãããŠãåã³ããã«æ»ãããã«ãå¥ã®ãã¥ãŒãžã®åãæ¿ãã®ãã§ãŒã³ãå®è¡ããããšãããã«ç°¡åã§ããããããããŸãã ã³ãŒãã¯
Githubã®EnvironmentPlayground.playgroundã«ãããŸãã
Main queueããå¥ã®ã¹ã¬ãããžã®é«äŸ¡ãªãžã§ãã®åãæ¿ãã¯åžžã«
éåæã§ããããšã«æ³šæããŠãã ããã
ãçŸåšã®ã¹ã¬ãããã¯ããžã§ããå¥ã®ãã¥ãŒã§çµäºããã®ãåŸ
æ©ããããã«åŒ·å¶ãããããããã¥ãŒã®
syncæ¹æ³ã«ã¯éåžžã«æ³šæããå¿
èŠããããŸãã
Main queueã§syncã¡ãœãããåŒã³åºããªãã§ãã ãããã¢ããªã±ãŒã·ã§ã³ã®deadlockã€ãªããããã§ãã ïŒããã«ã€ããŠã¯ä»¥äžã§è©³ãã説æããŸãïŒ
ã°ããŒãã«ãã¥ãŒ
ç¹å¥ã«äœæããå¿
èŠããããŠãŒã¶ãŒãã¥ãŒã«å ããŠã
iOSã·ã¹ãã ã¯ã
out-of-the-boxã°ããŒãã«ãã¥ãŒãéçºè
ã«æäŸããŸãã 圌ãã®5ïŒ
1.ïŒã·ãŒã±ã³ã·ã£ã«ãã¥ãŒ
Main queue ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒ
UI ïŒã䜿çšãããã¹ãŠã®æäœãè¡ãããŸãã
let main = DispatchQueue.main
ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒ
UI ïŒã
UIButtonãŸãã¯
UI-- UIButtonäœããè¡ã颿°ãŸãã¯ã¯ããŒãžã£ãŒãå®è¡ããå Žåã¯ããã®é¢æ°ãŸãã¯ã¯ããŒãžã£ãŒã
Main queueé
眮ããå¿
èŠããã
Main queue ã ãã®ãã¥ãŒã¯ãã°ããŒãã«ãã¥ãŒã®äžã§æãé«ãåªå
床ãæã£ãŠããŸãã
2.ïŒ
qoså質ãç°ãªããåªå
床ãç°ãªã4ã€ã®ããã¯ã°ã©ãŠã³ã
concurrent ïŒäžŠåïŒã°ããŒãã«ãã¥ãŒïŒ
ãããã®åãã¥ãŒ
Apple ã
Appleæœè±¡çãªããµãŒãã¹å質ã
qos ïŒ
Quality of Serviceç¥ïŒãæäžãã
Apple ãã¿ã¹ã¯ã«å¯ŸããŠäœããã¹ãããæ±ºå®ããå¿
èŠããããŸãã
ããŸããŸãª
qosã
qos ãããããã®ç®çã説æã
qos ã
.userInteractiveçŸåšãŠãŒã¶ãŒãšããåãããŠããã¿ã¹ã¯ã§ãã»ãšãã©æéã.userInteractiveã¿ã¹ã¯ã®å ŽåïŒã¢ãã¡ãŒã·ã§ã³ã¯å³åº§ã«å®è¡ãããŸãã ãŠãŒã¶ãŒã¯Main queueã§ãããè¡ããããããŸããããããã¯ã§ããã ãæ©ãè¡ãå¿
èŠããããŸãããŠãŒã¶ãŒã¯çŸåšãç§ãšããåãããŠããããã§ãã ãŠãŒã¶ãŒãç»é¢äžã§æãã¹ã¯ã€ãããéäžçãªç»ååŠçã«é¢é£ããäœããèšç®ããå¿
èŠãããããã®ãã¥ãŒã«èšç®ãé
眮ããç¶æ³ãæ³åã§ããŸãã ãŠãŒã¶ãŒã¯ç»é¢äžã§æãã¹ã©ã€ãããç¶ããŸãããããã«çµæã衚瀺ãããããã§ã¯ãããŸãããèšç®ã¯æéãããããããçµæã¯ç»é¢äžã®æã®äœçœ®ããããããã«é
ããŸãããå°ãªããšãMain queueãŸã æããèããŠãåå¿ããŸãã ãã®ãã¥ãŒã®åªå
床ã¯éåžžã«é«ããªã£ãŠããŸããã Main queueãããäœããªã£ãŠãMain queue ã.userInitiatedãŠãŒã¶ãŒã«ãã£ãŠéå§ããããã£ãŒãããã¯ãå¿
èŠãªã¿ã¹ã¯ã®å Žåãããã¯å¯Ÿè©±åã€ãã³ãã®å
éšã§ã¯ãªãããŠãŒã¶ãŒã¯å¯Ÿè©±ãç¶ããããã®ãã£ãŒãããã¯ãåŸ
ã£ãŠããŸãã æ°ç§ãããå ŽåããããŸãã åªå
床ã¯é«ãããåã®ãã¥ãŒãããäœã.utulityããŒã¿ã®ããŒããããŒã¿ããŒã¹ã®ã¯ãªã¢ãªã©ãå®äºãããŸã§ã«ããçšåºŠã®æéãå¿
èŠãšãã峿ã®ãã£ãŒãããã¯ãå¿
èŠãšããªãã¿ã¹ã¯ã®å Žåã ãŠãŒã¶ãŒãèŠæ±ããŠããªãããšãè¡ãããŠããŸããããã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯å¿
èŠã§ãã ã¿ã¹ã¯ã«ã¯æ°ç§ããæ°åãããå ŽåããããŸãã åªå
床ã¯åã®ãã¥ãŒãããäœãã.backgroundèŠèŠåã«é¢é£ãããå®è¡æéã«éèŠã§ã¯ãªãã¿ã¹ã¯ã ããšãã°ã backupsãŸãã¯webãµãŒãã¹ãšã®åæã ããã¯éåžžãããã¯ã°ã©ãŠã³ãã§å®è¡ããããã®ã§ã誰ãã¡ã³ããã³ã¹ãå¿
èŠãšããªãå Žåã«ã®ã¿çºçããŸãã ã»ãã®æ°åããæ°æéãããããªãã®ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã ãã¹ãŠã®ã°ããŒãã«ãã¥ãŒã®äžã§æãäœãåªå
床ãæã¡ãŸãã
ãŸããããã©ã«ãã®
.default concurrencyãã¥ãŒ
.defaultããããŸããããã¯ã
qos ããµãŒãã¹å質ã
qosäžè¶³ãå ±åã
qos ã æŒç®åã䜿çšããŠäœæãããŸãïŒ
DispatchQueue.global()
ä»ã®ãœãŒã¹ãã
qosæ
å ±ãå€å¥ã§ããå Žåã¯ããã䜿çšãããããã§ãªãå Žåã¯
.userInitiatedãš
.utilityéã§
qos䜿çšãããŸãã
ãããã®ã°ããŒãã«ãã¥ãŒã¯ãã¹ãŠ
SYSTEMã°ããŒãã«ãã¥ãŒã§ããããã®ãã¥ãŒå
ã®ã¿ã¹ã¯ã¯ç§ãã¡ã®ã¿ã¹ã¯ã ãã§ã¯ãªãããšãçè§£ããããšãéèŠã§ãã ãŸãã1ã€ãé€ããã¹ãŠã®ã°ããŒãã«ãã¥ãŒã
concurrent ïŒäžŠåïŒãã¥ãŒã§ããããšãç¥ãããšãéèŠã§ãã
ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹çšã®ç¹å¥ãªã°ããŒãã«ã·ãªã¢ã«ãã¥ãŒ-ã¡ã€ã³ãã¥ãŒ
Appleã¯ãå¯äžã®ã°ããŒãã«
serial ïŒã·ãŒã±ã³ã·ã£ã«ïŒãã¥ãŒãæäŸããŠããŸã-ããã¯ãäžèšã®
Main queueã§ãã ãã®ãã¥ãŒã§ã¯ã
UI倿Žã«é¢é£ããªããªãœãŒã¹éçŽçãªæäœïŒããšãã°ããããã¯ãŒã¯ããã®ããŒã¿ã®ããŠã³ããŒãïŒãå®è¡ããŠããã®æäœã®é
UIããããªãŒãºãããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããã€ã§ããŠãŒã¶ãŒã®æäœã«å¿çãããªãããã«ããããšã¯æãŸãããããŸããããžã§ã¹ãã£ãŒã§ã
ãã®ãããªãªãœãŒã¹éäžåã®æäœãä»ã®ã¹ã¬ãããŸãã¯ãã¥ãŒã«ãæµçšãããããšã匷ããå§ãããŸãã
ãã1ã€å³ããèŠä»¶ããããŸãã
Main queueã®ã¿ã
UIèŠçŽ ã倿Žã§ããŸãã
ããã¯ã
Main queue UIã¢ã¯ã·ã§ã³ã«ãå¿çãããã ãã§ãªãïŒã¯ãããããäž»ãªçç±ïŒããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ããã«ãã¹ã¬ããç°å¢ã§ã®ãæ··ä¹±ãããä¿è·ãããã€ãŸãããŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã¯ãå³å¯ã«é çªã«å®è¡ãããŸãã
UIèŠçŽ ãç°ãªããã¥ãŒã§ã¢ã¯ã·ã§ã³ãå®è¡ã§ããããã«ãããšãæç»ãç°ãªãé床ã§çºçããã¢ã¯ã·ã§ã³ã亀差ããç»é¢äžã§å®å
šã«äºæž¬äžèœã«ãªãå¯èœæ§ããããŸãã
Main queueãäžçš®ã®ãåæãã€ã³ãããšããŠäœ¿çšããç»é¢ã«ãæç»ãããããã¹ãŠã®ãŠãŒã¶ãŒãæ»ããŸãã
ãã«ãã¹ã¬ããã®åé¡
ã¿ã¹ã¯ã®äžŠååäœãèš±å¯ãããšããã«ãç°ãªãã¿ã¹ã¯ãåããªãœãŒã¹ã«ã¢ã¯ã»ã¹ããããšããäºå®ã«é¢é£ããåé¡ããããŸãã
äž»ã«3ã€ã®åé¡ããããŸãã
race condition -ã·ã¹ãã ãŸãã¯ã¢ããªã±ãŒã·ã§ã³ã®åäœãã³ãŒãã®äžéšãå®è¡ãããé åºã«äŸåããããã«ãã¹ã¬ããã·ã¹ãã ãŸãã¯ã¢ããªã±ãŒã·ã§ã³ã®èšèšã«ããããšã©ãŒpriority inversiondeadlock -è€æ°ã®ã¹ã¬ãããããããã®ã¹ã¬ããèªäœãå æãããªãœãŒã¹ãç¡éã«åŸ
æ©ããŠãããã«ãã¹ã¬ããã·ã¹ãã ã®ç¶æ³
ç«¶åç¶æ
privateãã¥ãŒã§
value倿°ãéåæã«å€æŽããçŸåšã®ã¹ã¬ããã§
valueã衚瀺ãããšã
race conditionæãåçŽãªã±ãŒã¹ãåçŸã§ããŸãã

éåžžã®å€æ°
valueãšããã倿Žããéåžžã®é¢æ°
changeValueããããæå³çã«
sleep(1)æŒç®åã䜿çšããŠã倿°ã®å€æŽã«ããªãã®æéããããããã«ããŸããã
asyncã䜿çšããŠ
changeValue颿°ã
changeValueå®è¡ãããšã倿Žããã
value倿°ã«é
眮ããåã«ãçŸåšã®ã¹ã¬ããã§
value倿°ãå¥ã®å€ã«ãªã»ããã§ããŸããããã
race conditionã§ãã ãã®ã³ãŒãã¯ã次ã®åœ¢åŒã§ã®å°å·ã«å¯Ÿå¿ããŠããŸãã

ã
race condition ããšåŒã°ããçŸè±¡ãæç¢ºã«ç€ºãå³ïŒ

asyncã¡ãœããã
sync眮ãæããŸãããïŒ

å°å·ãšçµæã®äž¡æ¹ã倿ŽãããŸããïŒ

<img
ãããŠãã
race condition ããšåŒã°ããçŸè±¡ããªãå³ïŒ

ãã¥ãŒã®
syncã¡ãœããã«ã¯éåžžã«æ³šæããå¿
èŠããããŸããããçŸåšã®ã¹ã¬ãããã¯ãžã§ããä»ã®ãã¥ãŒã§çµäºãããŸã§åŸ
æ©ããããã
syncã¡ãœããã¯ç«¶åç¶æ
ãé¿ããããã«éåžžã«äŸ¿å©ã§ãã
race conditionçŸè±¡ãã·ãã¥ã¬ãŒãããã³ãŒãã¯
ãGithubã®firstPlayground.playgroundã§è¡šç€ºã§ããŸãã åŸã§ãç°ãªãã¹ããªãŒã ã§åä¿¡ããæååã圢æãããšãã®å®éã®ã
race condition ãã瀺ããŸãã ãããªã¢ãã䜿çšããŠã¹ããªã³ã°ã圢æãããšã¬ã¬ã³ããªæ¹æ³ãææ¡ãããŸããããã«ãããã
race conditions ããåé¿ããçæãããã¹ããªã³ã°ãã¹ã¬ããã»ãŒãã«ããããšãã§ããŸãã
åªå
é äœã®é転
ã®æŠå¿µã¯ããªãœãŒã¹ã®ããã¯ã«å¯æ¥ã«é¢é£ããŠããŸãã
åªå
床ãäœïŒAïŒãšé«ïŒBïŒã®2ã€ã®ã¿ã¹ã¯ãã·ã¹ãã ã«ãããšããŸããæéT1ã§ãã¿ã¹ã¯ïŒAïŒã¯ãªãœãŒã¹ããããã¯ãããªãœãŒã¹ã®æäŸãéå§ããŸããæéT2ã§ãã¿ã¹ã¯ïŒBïŒã¯åªå
床ã®äœãã¿ã¹ã¯ïŒAïŒãæŒãåºããæéT3ã§ãªãœãŒã¹ãåŒãç¶ããŸãããã ãããªãœãŒã¹ãããã¯ãããŠãããããã¿ã¹ã¯ïŒBïŒã¯ä¿çãããã¿ã¹ã¯ïŒAïŒã¯å®è¡ãç¶ç¶ããŸããæéT4ã§ãã¿ã¹ã¯ïŒAïŒã¯ãªãœãŒã¹ã®ãµãŒãã¹ãå®äºããããã¯ãè§£é€ããŸããã¿ã¹ã¯ïŒBïŒã¯ãªãœãŒã¹ãäºæããŠãããããããã«å®è¡ãéå§ããŸããã¿ã€ã ã¹ãã³ïŒT4-T3ïŒã¯ãéå®åªå
é äœå転ãšåŒã°ããŸãããã®æéã«ã¯ãèšç»ã«ãŒã«ãšè«ççãªççŸããããŸããåªå
床ã®äœãã¿ã¹ã¯ãå®è¡ãããŠããéãåªå
床ã®é«ãã¿ã¹ã¯ãåŸ
æ©ããŠããŸããããããããã¯ææªã§ã¯ãããŸãããã·ã¹ãã ã§3ã€ã®ã¿ã¹ã¯ãæ©èœãããšããŸãïŒäœåªå
床ïŒAïŒãäžåªå
床ïŒBïŒãé«åªå
床ïŒCïŒïŒ
ãªãœãŒã¹ãã¿ã¹ã¯ïŒAïŒã«ãã£ãŠãããã¯ãããã¿ã¹ã¯ïŒCïŒã«ãã£ãŠå¿
èŠãšãããå Žåãåãç¶æ³ã芳å¯ãããŸã-é«åªå
床ã¿ã¹ã¯ããããã¯ãããŸãããããã¿ã¹ã¯ïŒBïŒããªãœãŒã¹ãåŸ
æ©ããïŒCïŒåŸïŒAïŒã«åã£ãŠä»£ãã£ããšããŸããã¿ã¹ã¯ïŒBïŒã¯ç«¶åã«ã€ããŠäœãç¥ããªãã®ã§ãäžå®æéïŒT5-T4ïŒã«ããã£ãŠå¥œããªã ãå®è¡ã§ããŸããããã«ãïŒBïŒã«å ããŠãã·ã¹ãã ã«ã¯ä»ã®ã¿ã¹ã¯ããããåªå
床ã¯ïŒAïŒããã倧ããïŒBïŒäœããªããŸãããããã£ãŠãæéïŒT6-T3ïŒã®æéã¯äžè¬ã«ç¡æéã§ãããã®ç¶æ³ã¯ãç¡å¶éã®åªå
é äœå転ãšåŒã°ããŸããäžè¬ã«ãåªå
床ã®å¶éã®å転ã¯é¿ããããšã¯ã§ããŸãããããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠç¡å¶éã®ãã®ã»ã©å±éºã§ã¯ãããŸãããåªå
床ã®äœããã¹ãŠã®ãå¹²æžãã¿ã¹ã¯ã®åªå
床ã匷å¶çã«äžããããšã§æé€ãããŸãã以äžã«ãDispatchWorkItemãªããžã§ã¯ãã䜿çšããŠçŸåšã®ãã¥ãŒå
ã®åã
ã®ã¿ã¹ã¯ã®åªå
床ãäžããæ¹æ³ã瀺ããŸãããããããã¯
ãããããã¯ã¯ããªãœãŒã¹ããã¯ããã¹ããããŠãããšãã«çºçããå¯èœæ§ãããã·ã¹ãã ã®ç·æ¥ç¶æ
ã§ããã·ã¹ãã ã«2ã€ã®ãªãœãŒã¹ïŒXããã³YïŒã䜿çšããäœïŒAïŒããã³é«ïŒBïŒåªå
床ã®2ã€ã®
ã¿ã¹ã¯ããããšããŸããæéT1ã§ãã¿ã¹ã¯ïŒAïŒã¯ãªãœãŒã¹Xããããã¯ããŸããæå»T3ã§ãªãœãŒã¹Yããããã¯ããåªå
ã¿ã¹ã¯ïŒBïŒãã¿ã¹ã¯ïŒBïŒããªãœãŒã¹Yãè§£æŸããã«ãªãœãŒã¹XïŒT4ïŒããããã¯ããããšãããšãä¿çãããã¿ã¹ã¯ïŒAïŒãç¶è¡ãããŸããæéT5ã§ãã¿ã¹ã¯ïŒAïŒãXãè§£æŸããã«ãªãœãŒã¹Yããããã¯ããããšãããšãçžäºããã¯ã®ç¶æ
ãçºçããŸããã¿ã¹ã¯ïŒAïŒãšïŒBïŒã®ããããå¶åŸ¡ãååŸã§ããŸãããçžäºããã¯ã¯ãã·ã¹ãã ããªãœãŒã¹ãžã®äŸåïŒãã¹ãïŒãã«ãã¹ã¬ããã¢ã¯ã»ã¹ã䜿çšããå Žåã«ã®ã¿å¯èœã§ãããã¹ãã䜿çšãããŠããªãå ŽåããŸãã¯ãªãœãŒã¹ãåªå
床å¢å ãããã³ã«ã䜿çšããŠããå Žåãçžäºããããã³ã°ãåé¿ã§ããŸããæçš¿ã®åé ã«ããã¿ã¹ã¯ã§ãããã¯ã°ã©ãŠã³ããã¥ãŒã§ãããã¯ãŒã¯ããããŒã¿ãåä¿¡ããåŸãã¡ã€ã³ãã¥ãŒã«æ»ãããã«syncã¡ãœããã䜿çšããããšãããšããããããã¯ïŒdeadockïŒãçºçããŸããã¢ããªã±ãŒã·ã§ã³ã§ãããããã¯ïŒïŒãçºçãããããã§ã¡ãœããsyncãåŒã³åºãmain queueãªãã§deadlockãã ããïŒå®éšç°å¢
å®éšã®ããã«ãæã
ã¯ã䜿çšããPlaygroundã¢ãžã¥ãŒã«Cç¡éã®æéã«åãããŠèª¿æŽPlaygroundSupportããã¯ã©ã¹PlaygroudPageæã
ã¯ãã¥ãŒã«çœ®ããããã¹ãŠã®ã¿ã¹ã¯ãå®äºãããžã®ã¢ã¯ã»ã¹ãåŸãããšãã§ããããšmain queueãPlaygroundcã³ãã³ãã§äœããã®ã€ãã³ããåŸ
ã€ã®ãæ¢ããããšãã§ãPlaygroundPage.current.finishExecution()ãŸããå¥ã®ã¯ãŒã«ãªæ©èœããããŸãPlayground- UIããŒã ã®å©ããåããŠãçããŠããããšå¯Ÿè©±ããæ©èœ PlaygroundPage.liveView = viewController
ããã³ã¢ã·ã¹ã¿ã³ããšãã£ã¿ãŒïŒAssistant EditorïŒãããšãã°ããäœæããå ŽåãviewControllerã確èªããã«ã¯ãã³ãŒããç¡å¶éã«å®è¡viewControllerããããã«æ§æPlaygroundããã¢ã·ã¹ã¿ã³ããšãã£ã¿ãŒãæå¹ã«ããã ãã§ãïŒAssistant EditorïŒãã³ãã³ããã³ã¡ã³ãåããŠãæåã§PlaygroundPage.current.finishExecution()忢ããPlaygroundå¿
èŠããããŸãã
Playgroundå®éšç°å¢ãã³ãã¬ãŒãã®cã³ãŒãã¯ãEnvironmentPlayground.playgroundãšããååã§ãGithubã«ãããŸãã1.æåã®å®éšãã°ããŒãã«ãã¥ãŒãšãžã§ã
ç°¡åãªå®éšããå§ããŸããããäžè²«æ§ã®ãã1ïŒæã
ã¯ãŸããäžççãªãã¥ãŒã®æ°ãå®çŸ©ããmainQueueããšããã- main queueããããŠ4ã€ã®äžŠåïŒconcurrentïŒqueues- ããuserInteractiveQueue ãšãããã©ã«ãã§èšå®ã§ããŸã- ïŒãžã§ããšããŠã10åã®åäžã®æåãšçŸåšã®ãã¥ãŒã®åªå
床ãå°å·ããããšãéžæããŸãã1æåãå°å·ããå¥ã®ã¿ã¹ã¯ãé«ãåªå
床ã§å®è¡ããŸããuserQueueutilityQueuebackgroundQueueconcurrent queuedefautQueue
tasktaskHIGH
2.第äºã®å®éšã¯ãã«é©çšãããŸãåæããã³éåæçã«ã°ããŒãã«ãã¥ãŒã«
ããšãã°ãã°ããŒãã«ãã¥ãŒãåãåã£ãããmethodã䜿çšããŠSYNCHRONOUSLYã«ããŸãã¯methodã䜿çšããŠASYNCHRONOUSLYã«userQueueã¿ã¹ã¯ãå®è¡ã§ããŸããåæå®è¡ã®å Žåããã¹ãŠã®ã¿ã¹ã¯ã次ã
ã«é çªã«éå§ãããæ¬¡ã®ã¿ã¹ã¯ãåã®ã¿ã¹ã¯ã®å®äºãæç¢ºã«åŸ
ã£ãŠããããšãããããŸããããã«ãæé©åãšããŠãå¯èœã§ããã°ãsync颿°ã¯çŸåšã®ã¹ã¬ããã§ã¯ããŒãºãããªã¬ãŒã§ããã°ããŒãã«ãã¥ãŒã®åªå
é äœã¯éèŠã§ã¯ãããŸãããããã¯ç§ãã¡ãèŠããã®ã§ããéåæå®è¡ã®å Žåãã¿ã¹ã¯ã®å®äºãšã°ããŒãã«ãã¥ãŒã®åªå
é äœãåŸ
ããã«ã¿ã¹ã¯ãéå§ããããšãããããŸããsyncasync
syncasync

userQueueã§ã®åªå
床ã®é«ãã³ãŒãã®å®è¡Playgroundããã®çµæãã¿ã¹ã¯userQueueãé »ç¹ã«å®è¡ãããããšã¯ãããŸããã3. 3çªç®ã®å®éšããã©ã€ããŒãã·ãªã¢ã«ãã¥ãŒ
ã°ããŒãã«ãã¥ãŒã«å ãPrivateãŠãã¯ã©ã¹ã€ãã·ã£ã©ã€ã¶ãŒã䜿çšããŠã«ã¹ã¿ã ãã¥ãŒãäœæã§ããŸãDispatchQueueïŒã«ã¹ã¿ã ãã¥ãŒã
äœæãããšãã«æå®ããå¿
èŠãlabelããã®ã¯AppleãéDNS衚èšïŒâcom.bestkora.mySerialâïŒãšããŠæå®ããããšããå§ãããäžæã®ã©ãã«ã§ãããã®ãã¥ãŒã¯ãããã¬ãŒã§ãã®ååã§è¡šç€ºãããŸãããã ããããã¯ãªãã·ã§ã³ã§ãããäžæã§ããéãä»»æã®æååã䜿çšã§ããŸãããã¥ãŒã®labelåæåæä»¥å€ã«ä»ã®åŒæ°ãæå®ããªãå ŽåPrivateãããã©ã«ãã§é 次ïŒ.serialïŒãã¥ãŒãäœæãããŸãããã¥ãŒãåæåãããšãã«èšå®ã§ããä»ã®åŒæ°ããããŸããããããã«ã€ããŠã¯å°ãåŸã§èª¬æããŸãããŠãŒã¶ãŒã©ã®ããã«èŠãŠPrivateãäžè²«ããå ŽæmySerialQueue䜿çšsyncããŠasyncïŒã¡ãœãã
ã®å Žåã¯ãåæ syncã®æé©åæ©èœãšããŠãããããç§ãã¡ã¯åãã¥ãŒå®éš3ãšåæ§ã®ç¶æ³ãèŠãã«ã¯ãéèŠã§ã¯ãããŸããsyncã黿µã®æµãã®ééãããªã¬ããããšãã§ããŸããããã¯ç§ãã¡ãèŠããã®ã§ããã¡ãœããã䜿çšãasyncãã·ãŒã±ã³ã·ã£ã«ãã¥ãŒãçŸåšã®ãã¥ãŒã«å¯ŸããŠéåæã«mySerialQueueã¿ã¹ã¯ãå®è¡ã§ããããã«
ãããšã©ããªããŸããïŒãã®å Žåãããã°ã©ã ã¯åæ¢ããããã®ã¿ã¹ã¯ããã¥ãŒã§å®äºãããŸã§åŸ
æ©ããŸããmySerialQueueã管çã¯ããã«ã¿ã¹ã¯ãå®äºããŸã
ã¿ã¹ã¯ãšåæã«ããããå®è¡ããŸã
4. QoS
ã¬ããã¯ãç§ãã¡ã®å²ãåœãŠPrivateã·ãªã¢ã«åç·serialPriorityQueueããµãŒãã¹å質QoSã.userInitiatedãšçãããéåæãã¥ãŒã®æåã®ä»äºã«å
¥ã
ããã®åŸã
ãã®å®éšã¯ãç§ãã¡ã®æ°ããå ŽæãããããšãçŽåŸãããã§ãããserialPriorityQueueãæ¬åœã«äžè²«ããŠããããšã®äœ¿çšã«ããããããasyncæ¹æ³ãã¿ã¹ã¯ã¯æ¬¡ã
ã«å®è¡ãããŸãå°çé ã«ïŒ
ãããã£ãŠããã«ãã¹ã¬ããã³ãŒããå®è¡ããã«ã¯ãmethodã䜿çšããã ãã§ã¯äžååasyncã§ãããã¥ãŒãç°ãªããããã¥ãŒèªäœãç§ã¯å¹³è¡ã§ãïŒ.concurrentïŒã䞊åïŒ.concurrentïŒãã¥ãŒã䜿çšããå®éš5ã§ã¯ããã©ã€ããŒã䞊åïŒ.concurrentïŒãã¥ãŒã䜿çšããåæ§ã®å®éšã衚瀺ãããŸãworkerQueueãããããåãã¿ã¹ã¯ããã®ãã¥ãŒã«å
¥ãããšããŸã£ããç°ãªãç¶æ³ã«ãªããŸããåªå
é äœã®ç°ãªãé æ¬¡Privateãã¥ãŒã䜿çšããŠ
ãæåã«ãã®ãã¥ãŒã«ã¿ã¹ã¯ãéåæçã«é
眮ããæ¬¡ã«ã¿ã¹ã¯
ãã¥ãŒserialPriorityQueue1c qos .userInitiatedãã¥ãŒserialPriorityQueue2c ã¿ã¹ã¯ã®qos .background
ãã«ãã¹ã¬ããå®è¡ããããã¿ã¹ã¯ã¯ããserialPriorityQueue1é«ããµãŒãã¹å質ã®ãã¥ãŒã§å®è¡ãããããšãå€ããªããŸãqos: .userIniatatedãããšãã°ã颿°ã䜿çšããŠããµãŒãã¹ã®å質ã倿Žããããšã«ãããä»»æã®ãã¥ãŒã§ã®ã¿ã¹ã¯ã®å®è¡ãDispatchQueueæå®ã®æéé
å»¶ãããããšãã§ããŸããnow() + 0.1asyncAfterqos
5. 5çªç®ã®å®éšã¯ããã©ã€ããŒã䞊åïŒåæïŒãã¥ãŒã«é¢ãããã®ã§ãã
PrivateparallelïŒ.concurrentïŒãã¥ãŒãåæåããã«ã¯ãPrivate queueãåæåãããšãã«attributesçããåŒæ°ã®å€ã瀺ãã ãã§åå.concurrentã§ãããã®åŒæ°ãæå®ããªãå ŽåãPrivateãã¥ãŒã¯é 次ïŒ.serialïŒã«ãªããŸããåŒæ°qosãå¿
é ã§ã¯ãªããåé¡ãªãã¹ãããã§ããŸããåçã®ãµãŒãã¹å質ã䞊åãã¥ãŒã«å²ãåœãŠãã¿ã¹ã¯ãæåã«ãã®ãã¥ãŒã«éåæçã«é
眮ããŠãããæ°ãã䞊åãã¥ãŒã¯å®éã«äžŠåã§ããããã®äžã®ã¿ã¹ã¯ã¯åæã«å®è¡ãããŸããã4çªç®ã®å®éšïŒ1ã€ã®é 次åãworkerQueueqos.userInitiated

workerQueueserialPriorityQueueïŒã圌ãã¯åŒæ°ãattributesçããèšå®ããŸã.concurrentïŒ
çµµã¯1ã€ã®é£ç¶ãããã¥ãŒãšæ¯èŒããŠå®å
šã«ç°ãªããŸãããã®å Žåã¯ãã¹ãŠã®ã¿ã¹ã¯ã¯ãå³å¯ã«ããããå®è¡ããããã«æ¥ãé åºã§è¡ãããŠãããããŠããç§ãã¡ã®äžŠåïŒãã«ãã¹ã¬ããïŒãã¥ãŒworkerQueueè€æ°ã®ã¹ã¬ããã«ãåå²ããã¿ã¹ã¯ãå®éã«äžŠè¡ããŠè¡ãããšãã§ããŸãããã€ãã®ã¯ãšã¹ããèšå·ã§
ãåŸã«ãã¥ãŒã«å
¥ãããããšããŠãworkerQueue䞊åã¹ã¬ããã§ã¯é«éã§ããã¬ããã»äœ¿çšäžŠåPrivateç°ãªãåªå
é äœãæã€ãã¥ãŒïŒãã¹ãŠã®workerQueue1C qos .userInitiatedãã¹ãŠã®workerQueue2C qos .background
ç°ãªãé
åãæãããšåããã¿ãŒã³Private2åç®ã®å®éšã§ããŒã¹ãããŸããworkerQueue1åªå
床ã®é«ãqueueã§ã¿ã¹ã¯ãå®è¡ãããé »åºŠãé«ãããšãããããŸããåŒæ°ã䜿çšããŠé
å»¶å®è¡ã§ãã¥ãŒãäœæattributesããã¡ãœããã䜿çšããŠé©åãªã¿ã€ãã³ã°ã§ãã®ã¿ã¹ã¯ã®å®è¡ãã¢ã¯ãã£ãåã§ããŸãactivate()ã
6. 6çªç®ã®å®éšã§ã¯ãDispatchWorkItemãªããžã§ã¯ãã䜿çšããŸãã
Dispatchãã¥ãŒå
ã®ããŸããŸãªã¿ã¹ã¯ã®å®è¡ã管çããããã®è¿œå æ©èœãå¿
èŠãªDispatchWorkItemå Žåã¯ããµãŒãã¹å質ãèšå®ã§ããã¿ã¹ã¯ãäœæã§ããŸãqosã
ããã«ãããããã©ãŒãã³ã¹ã«åœ±é¿ããŸãã[.enforceQoS]æºåäžã«ãã©ã°ãèšå®ããããšã«ããDispatchWorkItemããã®ã¿ã¹ã¯ã®highPriorityItemä»ã®ã¿ã¹ã¯ãããã¿ã¹ã¯ã®åªå
床ãé«ããªããŸãåããã¥ãŒïŒ
ããã«ãããDispatch Queueç¹å®ã®ãµãŒãã¹å質ã«å¯ŸããŠç¹å®ã®ã¿ã¹ã¯ã®åªå
床ã匷å¶çã«äžããããšãã§ãããããqosãåªå
床ã®é転ãã®çŸè±¡ã«å¯ŸåŠã§ããŸãã 2ã€ã®ã¿ã¹ã¯highPriorityItemãææ°ã®ã¿ã¹ã¯ããéå§ããããšããäºå®ã«ããããããããã©ã°[.enforceQoS]ãšåªå
é äœãé«ãããããšã«ãããæåããå®è¡ãããŠããããšãããããŸãã.userInteractiveãããã«ãã¿ã¹ã¯highPriorityItemã¯ç°ãªããã¥ãŒã§è€æ°åå®è¡ã§ããŸããæã
ã¯ãã©ã°ãåé€ããå Žå[.enforceQoS]ïŒ
ãžã§ãã¯highPriorityItemããµãŒãã¹ã®å質ã«ãªããŸãqos圌ããå®è¡ãããªã³ã«èšå®ãããŠããã
ãããããŸã 圌ãã¯éåžžã«åãã¥ãŒã®å§ãŸãã«é¥ããŸããããããã¹ãŠã®å®éšã®ã³ãŒãã¯ãGithubã®firstPlayground.playgroundã«ãããŸããã¯ã©ã¹ã§DispatchWorkItemããããã£ãããisCancelledãšã¡ãœããã®æ°ãïŒ
ã¡ãœããã®ååšã«ããããããcancel()ã®ããDispatchWorkItem GCDããŸã ããã§ã«ç¹å®ã®ã©ã€ã³äžã§éå§ãããåè·¯ããåé€ããŸãããçŸåšã§ããããšã¯DispatchWorkItemãã¡ãœããã䜿çšããŠããªã¢ãŒãããšããŠããŒã¯ããããšcancel()ã§ããã¡ãœããåŒã³åºãã®å Žåcancel()åã«çºçããDispatchWorkItemæ¹æ³ã«ãã£ãŠãã¥ãŒã«å
¥ããããŸãasyncãããã¯DispatchWorkItemå®è¡ãããŸãããç¹å®ã®ãã¥ãŒã§éå§ãããã¯ããŒãžã£ãŒãåé€ããæ¹æ³ãããããªããšããäºå®Operationã ãã§ãªããã¡ã«ããºã ã䜿çšããå¿
èŠãããå Žåãããçç±ã®1ã€ã§ããã¯ã©ã¹ãšãã®ã¡ãœãããããã³ã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã¡ãœããã䜿çšã§ããŸããGCDGCDDispatchWorkItemnotify (queue:, execute:)DispatchQueue async(execute workItem: DispatchWorkItem)
ãã¹ãã®æåã«æç€ºãããåé¡ã解決ããããã«-ãããã¯ãŒã¯ããã€ã¡ãŒãžãããŠã³ããŒãããŸãïŒç¹å®ã®ã¢ãã¬ã¹ã§ããããã¯ãŒã¯ãããããŒã¿ãååŸããããšã§æ§æãããã¯ã©ã¹ã®
ã€ã³ã¹ã¿ã³ã¹ã®åœ¢åŒã§åæã¿ã¹ã¯ã圢æããŸãã颿°ã䜿çšããŠããµãŒãã¹å質ã§äžŠåã°ããŒãã«ãã¥ãŒã§éåæãžã§ããå®è¡ããworkItemDispatchWorlItemdataimageURLworkItemqueueqos: .utility queue.async(execute: workItem)
æ©èœã䜿çšãã workItem.notify(queue: DispatchQueue.main) { if let imageData = data { eiffelImage.image = UIImage(data: imageData)} }
ããŒã¿ã¢ããããŒãã®çµäºã«é¢ããéç¥ãåŸ
ã£ãŠããŸãdataããããèµ·ãã£ãããç§ãã¡ã¯ãç»åèŠçŽ ãæŽæ°UI eiffelImageïŒ
ã³ãŒããäžã«é
眮ãããŠããã®GithubäžLoadImage.playgroundããã¿ãŒã³1.ãããã¯ãŒã¯ããç»åãããŠã³ããŒãããããã®ã³ãŒããªãã·ã§ã³
2ã€ã®åæã¿ã¹ã¯ããããŸãããããã¯ãŒã¯ããããŒã¿ãåä¿¡ãã let data = try? Data(contentsOf: imageURL)
dataãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããŒã¿ã«åºã¥ãæŽæ°ïŒUIïŒ eiffelImage.image = UIImage(data: data)
ããã¯GCDãã³ã³ããŒãã³ãUIKitãã¡ã€ã³ã¹ã¬ããããæä»çã«æ©èœãããããããã¯ã°ã©ãŠã³ãã¹ã¬ããã§äœæ¥ãè¡ããçµæã衚瀺ããããã«ã¡ã€ã³ã¹ã¬ããã«è¿ãå¿
èŠãããå Žåã«ããã«ãã¹ã¬ããã¡ã«ããºã ã䜿çšããŠå®è¡ãããå
žåçãªãã¿ãŒã³ã§ããããã¯ãåŸæ¥ã®æ¹æ³ã§è¡ãããšãã§ããŸãã
æ¢è£œã®éåæAPIã䜿çšããããURLSessionïŒ
ãŸãã¯usingã䜿çšãDispatchWorlItemãŸãã
æåŸã«ãåæã¿ã¹ã¯ãåžžã«éåæãã·ã§ã«ãã«ãã©ãããããŠå®è¡ã§ããŸãã
ãã®ãã¿ãŒã³ã®ã³ãŒãã¯LoadImage.playgroundã«ãããŸãgithubã§ããã¿ãŒã³2ãæ©èœã¯ãGCDã䜿çšããŠããŒãã«ãã¥ãŒããã³ã³ã¬ã¯ã·ã§ã³ãã¥ãŒã®ãããã¯ãŒã¯ããç»åãããŠã³ããŒãããŸãã
äžã€ã ãã§æ§æãããŠéåžžã«ç°¡åãªã¢ããªã±ãŒã·ã§ã³ã®äŸãèããŠã¿ãŸãããImage Table View Controller现èã®ã¿ãã€ã³ã¿ãŒãããããããŠã³ããŒããããã€ã¡ãŒãžãšããŒãããã»ã¹ãç€ºãæŽ»åã®ææšãå«ãŸããŠããããŒãã«ãïŒ
ããã®ã¯ã©ã¹ã§ããImageTableViewControllerã¹ã¯ãªãŒã³ã®ãµãŒãã¹ãã©ã°ã¡ã³ãImage Table View ControllerïŒ
ããã³ã¯ã©ã¹ImageTableViewCellããŒããããŠããããŒãã«ã»ã«ã«ã€ããŠã¯ã imageïŒ
ã€ã¡ãŒãžã¯éåžžã®å€å
žçãªæ¹æ³ã§ããŒããããŸããã¯ã©ã¹ã®ã¢ãã«ImageTableViewControllerã¯8ã®é
åã§ãURLsïŒ- ãšããã§ã«å¡
- ãŽã§ããã£ã¢
- ã¹ã³ããã©ã³ãã®å
- Cassiniãµãã©ã€ã-ä»ã®ãããã¯ãŒã¯ãããã¯ããã«é·ããããã¯ãŒã¯ããã®èªã¿èŸŒã¿
- ãšããã§ã«å¡
- ãŽã§ããã£ã¢
- ã¹ã³ããã©ã³ãã®å
- 忥µå
ã¢ããªã±ãŒã·ã§ã³ãèµ·åãã8ã€ã®ç»åãã¹ãŠã衚瀺ããã®ã«ååãªéãã§ã¹ã¯ããŒã«ãéå§ãããšãç»é¢ãé¢ãããŸã§Cassini Satelliteãèµ·åããªãããšãããããŸããæããã«ãä»ã®ãã¹ãŠã®ãã®ãããããŒãã«ããªãæéãããããŸãã
ããããæåŸãŸã§ã¹ã¯ããŒã«ããŠæåŸã®ã»ã«ã§ã忥µããèŠãåŸãéåžžã«çãæéã®åŸãçªç¶ã«ãã·ãŒãè¡æã«çœ®ãæããããããšãããããŸããã
ããã¯ããã®ãããªåçŽãªã¢ããªã±ãŒã·ã§ã³ã®èª€ã£ãæ©èœã§ããåé¡ã¯äœã§ããïŒ
å®éã«ã¯ãããŒãã«ã®ã»ã«ã¯ã¡ãœããã®ãããã§åå©çšå¯èœdequeueReusableCellã§ããã»ã«ïŒæ°èŠãŸãã¯åå©çšïŒãç»é¢ã«ããããããã³ã«ããããã¯ãŒã¯ããéåæã«ç»åãããŠã³ããŒãããïŒãã®æç¹ã§ããã€ãŒã«ããå転ããŸãïŒãããŠã³ããŒããå®äºããŠç»åãåä¿¡ããããšããã«ãUIãã®ã»ã«ãæŽæ°ãããŸããããããç»åãããŒããããã®ãåŸ
ããã«ãããŒãã«ãã¹ã¯ããŒã«ãç¶ããŠãã»ã«ïŒãCassiniãïŒãããèªäœãæŽæ°ããã«ç»é¢ãé¢ããŸãUIããã ããæ°ããç»åãäžã«è¡šç€ºãããç»é¢ãåºãåãã»ã«ãåå©çšãããŸãããå¥ã®ç»åïŒã忥µãïŒã«ã¯ããã«ããŒãããã³æŽæ°ãããŸãUIããã®æç¹ã§ããã®ã»ã«ã§ä»¥åã«èµ·åãããCassiniã®ããŠã³ããŒããè¿ãããç»é¢ãæŽæ°ãããŸãããããã¯ééã£ãŠããããã§ãã圌ãã¯ããŸããŸãªæã«æ»ã£ãŠããŸãïŒ
ã©ãããã°ç¶æ³ãä¿®æ£ã§ããŸããïŒã¡ã«ããºã ã®ãã¬ãŒã ã¯ãŒã¯å
ã§ãGCDç»é¢ãé¢ããã»ã«ã®ç»åã®èªã¿èŸŒã¿ããã£ã³ã»ã«ããããšã¯ã§ããŸãããimageDataããããã¯ãŒã¯ããæ¥ããšãã«URLããã®ããŒã¿ã®èªã¿èŸŒã¿ã®åå urlãšãªã£ããã®ã確èªãããŠãŒã¶ãŒãçŸæç¹ã§ãã®ã»ã«ã«å
¥ããããã®ãšæ¯èŒã§ããŸãimageURLïŒ
ããã§ãã¹ãŠãæ£åžžã«æ©èœããŸãããããã£ãŠããã«ãã¹ã¬ããããã°ã©ãã³ã°ã«ã¯éæšæºã®æ³ååãå¿
èŠã§ããå®éããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®ããã€ãã®ããšã¯ãã³ãŒããèšè¿°ãããé åºãšã¯ç°ãªãé åºã§è¡ãããŸããä»é²GCDTableViewControllerã¯äžã«ããã®Githubããã¿ãŒã³3. DispatchGroupsã®äœ¿çš
éåæã«å®è¡ããå¿
èŠãããã¿ã¹ã¯ãããã€ããããããããå®äºããã®ãåŸ
ã€å ŽåãDispatchGroupäœæãéåžžã«ç°¡åãªã°ã«ãŒããé©çšãããŸãã let imageGroup = DispatchGroup()
æã
ã¯ãããããã¯ãŒã¯ããã4ã€ã®ç°ãªãç»åãããŠã³ããŒãããå¿
èŠããããšããŸãããïŒ
ã¡ãœããã¯ãqueue.async(group: imageGroup)ã°ã«ãŒãã«ä»»æã®å²ãåœãŠã远å ããããšãã§ããŸãïŒåæïŒä»»æã®è¡ã§å®è¡ãããŠããqueueïŒ
ç§ãã¡ã¯ãã°ã«ãŒããäœæimageGroupããæ³ã«ãã£ãŠããã®ã°ã«ãŒãã«é
眮ãããasync (group: imageGroup)ã°ããŒãã«ãªãã©ã¬ã«ã¿ãŒã³ãžã®éåæããŒãã®ç»åã®ããã®2ã€ã®å²ãåœãŠDispatchQueue.global()ãããŠDispatchQueue.global(qos:.userInitiated)ããµãŒãã¹å質ã§ã°ããŒãã«äžŠåãã¥ãŒã«ã€ã¡ãŒãžãéåæçã«ããŒããã2ã€ã®ã¿ã¹ã¯.userInitiatedãç°ãªããã¥ãŒã§å®è¡ãããŠããã¿ã¹ã¯ãåãã°ã«ãŒãã«è¿œå ã§ããããšãéèŠã§ããã°ã«ãŒãå
ã®ãã¹ãŠã®ã¿ã¹ã¯ãå®äºãããšã颿°notifyãåŒã³åºãããŸã-ããã¯ã°ã«ãŒãå
šäœã®äžçš®ã®ã³ãŒã«ããã¯ãããã¯ã§ããããã¹ãŠã®ç»åãåæã«ç»é¢ã«é
眮ããŸãã
ã°ã«ãŒãã«ã¯ã¹ã¬ããã»ãŒããªå
éšã«ãŠã³ã¿ãŒãå«ãŸããŠãããã¡ãœããã䜿çšããŠã¿ã¹ã¯ãã°ã«ãŒãã«è¿œå ããããšèªåçã«å¢å ããŸãasync (group: imageGroup)ãã¿ã¹ã¯ãå®è¡ããããšãã«ãŠã³ã¿ãŒã1ã€æžãããã¹ãŠã®é·ææäœãå®äºããåŸã«ã³ãŒã«ããã¯ãããã¯ãåŒã³åºãããããšãä¿èšŒãããŸããåææäœã®ã°ã«ãŒãã®åœ¢æã«é¢ããå®éšã¯ãGithubã®Playground GroupSyncTasks.playgroundã§æç€ºãããŸããã°ã«ãŒãã«åææäœã ãã§ãªãéåææäœãããå Žåã¯ãã¹ã¬ããã»ãŒãã«ãŠã³ã¿ãŒãæåã§å¶åŸ¡ã§ããŸããenter()ã¡ãœããã¯ã«ãŠã³ã¿ãŒãå¢ãããã¡ãœããã¯leave()æžãããŸããGithubã®Playground GroupAsyncTasks.playgroundã䜿çšããŠãã°ã«ãŒãå
ã®éåææäœã®é
眮ãåŠç¿ããŸããéåæã¿ã¹ã¯ãã°ã«ãŒãã«é
眮ããç»é¢ã®äžéšã«è¡šç€ºããŸãã
æ¯èŒã®ããã«ãç»é¢ã®äžéšã«ãéåžžã®æ¹æ³ã§ååŸããåãç»åãã°ã«ãŒãã«ãŸãšããã«æ¬¡ã
ã«é
眮ããŸããããªãã¯ããã«å
é ã«åãç»åã®å€èгã®éããæããã ããããäžéšã«ããïŒåãã«ã¡ãœããåŒã³åºãããæ¬¡ã
ãšãç»é¢äžéšã®ç»åãããã³ç»é¢ã®ãã¹ãŠäžåºŠç»åããããããã§ãããasyncGroup ()ããasyncUsual ()éã®é åºã§ïŒ
æèŸŒã¿ãæ··åæäœã®ã°ã«ãŒãïŒåæããã³éåæïŒ
çµæã¯åãã«ãªããŸãããã¿ãŒã³4.ã¹ã¬ããã»ãŒã倿°ãåé¢ãã¥ãŒ
ã®ã¯ãããŒã¹ãã§ç§ãã¡ã®æåã®å®éšã«æ»ã£ãŠè¡ããGCDã§Swift 3ïŒãšè¡ã®ã¿ã¹ã¯ã®æç³»åïŒåçŽæ¹åïŒã®ã·ãŒã±ã³ã¹ãç¶æããããã«ãã£ãŠãæ°Žå¹³ãªæ¹æ³ã§ç°ãªãã©ã€ã³äžã®ã¿ã¹ã¯ã®çµæããŠãŒã¶ã«æç€ºããããš
ãç§ã¯éåžžã©ããã®çµææ ŒçŽããããã«äœ¿çšãããããšãèšã£ãŠããNEpotochno-ãã»ãã¥ã¢ã§Swift 3ãæååusualString: Stringãããã³ã¹ã¬ããã»ãŒãïŒã¹ã¬ããã»ãŒãïŒæååsafeString: ThreadSafeStringïŒ var safeString = ThreadSafeString("") var usualString = ""
ãã®ã»ã¯ã·ã§ã³ã®ç®çã¯ãã¹ã¬ããã»ãŒããªæååãã§ã©ã®ããã«é
眮ãããã瀺ãSwift 3ããšã§ããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸããã¹ã¬ããã»ãŒãæååã䜿çšãããã¹ãŠã®å®éšã¯ãGithubã®Playground GCDPlayground.playgroundã§è¡ãããŸããIãèç©äž¡æ¹ã®è¡ã®æ
å ±ãé ã«ãããå²ãåœãŠã倿ŽããŸãusualStringãšsafeStringïŒ
ã§SwiftããŒã¯ãŒãã§å®£èšãããä»»æã®å€æ°ãletäžå®ã§ãããããã¹ã¬ããã»ãŒãïŒthread-safeïŒãããŒã¯ãŒãvarã䜿çšããŠå€æ°ã宣èšãããšã倿°ã¯å¯å€ïŒmutableïŒããã³éã¹ã¬ããã»ãŒãïŒthread-safeïŒç¹å¥ã«èšèšããããŸã§ã2ã€ã®ã¹ã¬ãããåãã¡ã¢ãªãããã¯ãåæã«å€æŽãå§ãããšããã®ã¡ã¢ãªãããã¯ãç Žæããå¯èœæ§ããããŸããããã«ãããã¹ã¬ããã§å€æ°ã®å€ãå¥ã®ã¹ã¬ããã§æŽæ°ãããŠãããšãã«å€æ°ãèªã¿åããšããå€ãå€ããã€ãŸãç«¶åç¶æ
ïŒrace conditionïŒãèªã¿åãããå±éºããããŸããã¹ã¬ããã»ãŒãã®çæ³çãªãªãã·ã§ã³ã¯ã次ã®å Žåã§ãã- èªã¿åãã¯åæçã«çºçãããã«ãã¹ã¬ããåãããŸã
- ã¬ã³ãŒãã¯éåæã§ãªããã°ãªãããçŸåšãã®å€æ°ã§åäœããå¯äžã®ã¿ã¹ã¯ã§ãªããã°ãªããŸãã
幞ããªããšã«ãGCDããªã¢ïŒbarrierïŒãšåé¢ãã¥ãŒã䜿çšããŠè§£æ±ºãããšã¬ã¬ã³ããªæ¹æ³ãæäŸããŸããããªã¢GCDã¯1ã€ã®è峿·±ãããšãè¡ããŸãããã¥ãŒãå®å
šã«ç©ºã«ãªãç¬éãåŸ
ã£ãŠãããã¯ããŒãºãå®è¡ããŸããããªã¢ãŒãã¯ããŒãžã£ãŒã®å®äºãéå§ãããšããã«ããã¥ãŒããã®æéäžã«ä»ã®ã¯ããŒãžã£ãŒãå®è¡ããªãããã«ããåºæ¬çã«åæé¢æ°ãšããŠæ©èœããŸããããªã¢ã«ããã¯ããŒãžã£ãçµäºãããšããã«ããã¥ãŒã¯éåžžã®åäœã«æ»ããèªã¿åããŸãã¯å¥ã®æžã蟌ã¿ãšåæã«èšé²ãå®è¡ãããªãããšãä¿èšŒãããŸããã®ã¯ããããã¹ã¬ããã»ãŒããªã¯ã©ã¹ãã©ã®ããã«èŠããããèŠãŠã¿ãŸãããThreadSafeStringïŒ
颿°isolationQueue.syncãèªã¿ãåè·¯ãéä¿¡ããããã«{result = self.internalString}ãåé¢ã®ç§ãã¡ã®å ŽæãisolationQueueããŠçµæãè¿ãåã«ãçµäºãåŸ
ã£ãŠããŸãresultããã®åŸãèªã¿åãçµæãåŸãããŸããåæåŒã³åºããè¡ããªãå Žåã¯ãã³ãŒã«ããã¯ãããã¯ãå°å
¥ããå¿
èŠããããŸãããã¥ãŒã¯isolationQueue䞊åïŒ.concurrentïŒã§ããããããã®ãããªåæèªã¿åãã¯äžåºŠã«æ°åå®è¡ã§ããŸãããã®é¢æ°isolationQueue.async (flags: .barrier)ã¯ããrecordãããaddãããŸãã¯ãinitializeãã®ã¯ããŒãºãåé¢ãã¥ãŒã«éä¿¡ããŸãisolationQueueããã®é¢æ°asyncã¯ããã¬ã³ãŒãããã远å ãããŸãã¯ãåæåãã®ã¯ããŒãºãå®éã«è¡ãããåã«å¶åŸ¡ãè¿ãããããšãæå³ããŸããããªã¢éšå(flags: .barrier)ã¯ããã¥ãŒå
ã®åã¯ããŒãžã£ãŒã®å®è¡ãå®äºãããŸã§ã¯ããŒãžã£ãŒãå®è¡ãããªãããšãæå³ããŸãããã®ä»ã®é害ã¯ãããªã¢ã®åŸã«é
眮ãããããªã¢ãå®äºããåŸã«å®è¡ãããŸããå®éšã®çµæDispatchQueuesãã¹ã¬ããã»ãŒããªïŒæç€ºthread-safeïŒã©ã€ã³safeString: ThreadSafeStringãšæ³ç·ã¯usualString: Stringãäžã«ããã®Githubäžã®éã³å ŽGCDPlayground.playgroundããããã®çµæãèŠãŠã¿ãŸãããã1.颿°syncã°ããŒãã«å¹³è¡ç·ã§DispatchQueue.global(qos: .userInitiated)ã«é¢ããŠPlaygroundïŒ
åŸæ¥ã®éã¹ããªãŒã ã»ãŒãã©ã€ã³ã®çµæusualStringãMATCHã®ã¹ã¬ããã»ãŒããªæååã«çµæsafeStringã2.颿°asyncã°ããŒãã«å¹³è¡ç·ã§DispatchQueue.global(qos: .userInitiated)ã«é¢ããŠPlaygroundïŒ
åŸæ¥ã®éã¹ããªãŒã ã©ã€ã³ã»ãŒãã®çµæusualStringãDO NOT MATCHã¹ã¬ããã»ãŒããªæååã§çµæãååŸããŸãsafeStringã3.æ©èœsyncã®Privateã·ãªã¢ã«ã©ã€ã³DispatchQueue (label: "com.bestkora.mySerial")éã³å Žã«é¢é£ããŠïŒ
å¹³éäžã®çµæã¯ãã¹ã¬ããã»ãŒãã§ã¯ãããŸããã©ã€ã³usualStringãMATCHã®çµæãã¹ã¬ããã»ãŒããªæååã«safeStringã4.æ©èœasyncäžã®Privateã·ãªã¢ã«ã©ã€ã³DispatchQueue (label: "com.bestkora.mySerial")ã«é¢ããŠPlaygroundïŒ
åŸæ¥ã®éã¹ããªãŒã ã©ã€ã³ã»ãŒãã®çµæusualStringãDO NOT MATCHã¹ã¬ããã»ãŒããªæååã«çµæãsafeStringã5. asyncã¿ã¹ã¯ã®æ©èœ
ãããŠ
äžã®Privateã·ãªã¢ã«åç·DispatchQueue (label: "com.bestkora.mySerial", qos : .userInitiated)ïŒ
çµæã¯ãã¹ã¬ããã»ãŒããªã©ã€ã³äžã«ãéåžžã§ã¯ãããŸããusualStringãMATCHã®ã¹ã¬ããã»ãŒããªæååã®çµæãsafeStringã6. asyncã¿ã¹ã¯ã®æ©èœ
ãããŠ
ç°ãªãã®Privateé£ç¶ããã©ã€ã³DispatchQueue (label: "com.bestkora.mySerial", qos : .userInitiated)ãããã³DispatchQueue (label: "com.bestkora.mySerial", qos : .background)ïŒ
åŸæ¥ã®éã¹ããªãŒã ã©ã€ã³é庫ã®çµæusualStringãDO NOT MATCHã¹ã¬ããã»ãŒããªæååã®çµæãšsafeStringã7. asyncã¿ã¹ã¯ã®æ©èœ
ãããŠ
äžã®Privateå¹³è¡ç·DispatchQueue (label: "com.bestkora.mySerial", qos : .userInitiated, attributes: .concurrent)ïŒ
åŸæ¥ã®éã¹ããªãŒã ã©ã€ã³é庫ã®çµæusualStringãDO NOT MATCHã¹ã¬ããã»ãŒããªæååã®çµæãšsafeStringã8. asyncã¿ã¹ã¯ã®æ©èœ
ãããŠ
andã䜿çšããç°ãªãPrivate䞊åãã¥ãŒã§ïŒéåžžã®ã¹ã¬ããã»ãŒãã©ã€ã³ã§ã®çµæãã¹ã¬ããã»ãŒãã©ã€ã³ã§ã®çµæãšäžèŽããªãã9.æ©èœã®åªå
é äœã§Cã®å€æŽïŒåŸæ¥ã®éã¹ããªãŒã ã©ã€ã³é庫ã®çµæãDO NOT MATCHã¹ã¬ããã»ãŒããªæååã®çµæãšã10.æ©èœã®åªå
é äœã®C倿ŽïŒæ®éã¹ã¬ããã»ãŒãã§ã¯ãªãç·äžçµæãMATCHã®ã¹ã¬ããã»ãŒãã©ã€ã³äžã®çµæãžã§ããšããŠqos : .userInitiatedqos : .background
usualStringsafeStringasyncAfter (deadline: .now() + 0.0, qos: .userInteractive)
usualStringsafeStringasyncAfter (deadline: .now() + 0.1, qos: .userInteractive)
usualStringsafeString
ãããŠ
æéééã§ããã«ãã¹ã¬ããã®å²ãåœãŠãããå Žæ
ãããŠ
ç°ãªããã¥ãŒã§çºçãããã1ã€ã®äžŠåïŒ.concurrentïŒãã¥ãŒã§çºçããusualStringãšãéåžžã®è¡ãšã¹ã¬ããã»ãŒããªè¡ã®éã§äžäžèŽãçºçããŸãsafeStringãã¹ã¬ããã»ãŒããªæååã䜿çšããŠsafeStringãæã
ã¯ããã°ããã¥ãŒã®ããããã£ãšã®åæãšéåæã®æ©èœãèŠãããšãã§ããå³åŽã®ãé³¥ç°ãã¯ã察å¿ããã¿ã¹ã¯ã®å®è¡ã¯ã次ã®ãšããã§ãã
ããªãã䜿çšããŠããªãå Žåã¯Playgroundãã¢ããªã±ãŒã·ã§ã³ãããããŠXcode 8ããã䜿çšããããšãå¯èœã§ããThread Sanitizer決æã®ããã«race conditionãThread Sanitizerã¢ããªã±ãŒã·ã§ã³å®è¡ã®æ®µéã§åäœããŸããã¹ããŒã ïŒSchemeïŒãç·šé
ããããšã§éå§ã§ããŸãããã®äŸã§ã¯ãç«¶åç¶æ
ã®æ€åºã衚瀺ãããŸããTsanã¢ããªã±ãŒã·ã§ã³ã³ãŒãã¯ãªã³ã§ãgithubã®ãçµè«ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã®åé¡ã解決ããGCDããã®ããã€ãã®ãŠãŒã¹ã±ãŒã¹ãæ€èšããŸããSwift 3ãæ¬¡ã®èšäºã§ã¯Operationsããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®å®éã®äœ¿çšã«é¢ãã質åã«ã€ããŠèª¬æããŸãSwift 3ãPSçŸåšGCD APIãã¹ãŠã®ãã©ãããã©ãŒã ã§å©çšå¯èœã§ããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ãäœæããåªããæ¹æ³ãæäŸããŸããããããçŸåšã®ããŒãžã§ã³ã«Swift 3ã¯ããã«ãã¹ã¬ãããèšè¿°ããããã®æ§ææ§é ããããŸãããéçºããŒã Swiftã¯ããã«ãã¹ã¬ãããããéäžçã«åãäžããããŒãžã§ã³Swift 5ïŒ2018ïŒã®ãã«ãã¹ã¬ããæ§æã®å®éã®å€æŽãæºåãã2017幎æ¥/å€ã«è°è«ãéå§ãããããã§ã¹ãã2017幎ã®ç§ãŸã§ãIBM ã®ããã°ã©ãã³ã°èšèªã®æ¥ã§ã¯ãªã¹ã»ã«ãããŒã¯ãæ¢åã®ãã«ãã¹ã¬ããããã°ã©ãã³ã°GCD APIãšasync颿°ã䜿çšãããšããéåœã®ãã©ããããã«ã€ãªãããã³ã¡ã³ããªãã§ã©ã®ããŒã¿/ç¶æ
ãèªèããã®ãéåžžã«é£ãããšè¿°ã¹ãŸãããç¬èªã®ãäœDispatch Queueããé¢é£ããã¿ã¹ã¯ã¯ããããã®è¡ã«ãã£ãŠè¡ãïŒ
æ¹åãã«ãã¹ã¬ããã®ããã®å¯èœãªåéã®äžã€-ã®äœ¿çšã§ãã俳åªã®ã¢ãã«ïŒä¿³åªãã¢ãã«ã§ãããïŒåactor-ã§ãå®éã«ã¯ãDispatchQueue+ ã¹ããŒã¿ã¹ãã®å Žæãåäœãã+ ãªãã¬ãŒã·ã§ã³ãã®è¡ã§å®è¡ïŒ
ããããããã¯å€ãã®ãªãã¡ãŒã®1ã€ã«ãããŸãããããŸãæ€èšããactorsãasync/awaitãäžå¯åæ§ããã¡ã¢ãªã¢ãã«ãã®ä»ã®é¢é£ãããã¯ããã«ãã¹ã¬ããã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒã®äž¡æ¹ã§æ°ããã¢ãããŒããžã®ãæãéãããããéåžžã«éèŠã§ããããã§é²åSwiftãèŠãããšãã§ããŸãããã®èšäºã¯ããã«ãã¹ã¬ããããã°ã©ãã³ã°ã倧éã«ãããããiTunesã§ãã¹ããããŠããStanford CS193p Winter 17ã³ãŒã¹ïŒiOS 10ããã³Swift 3ã«åºã¥ãïŒã䜿çšããŠãSwiftã§iOSããã°ã©ãã³ã°ãåŠç¿ãã人ã«åœ¹ç«ã€å ŽåããããŸããåç
§è³æ
WWDC 2016. Concurrent Programming With GCD in Swift 3 (session 720)WWDC 2016. Improving Existing Apps with Modern Best Practices (session 213)WWDC 2015. Building Responsive and Efficient Apps with GCD.Grand Central Dispatch (GCD) and Dispatch Queues in Swift 3iOS Concurrency with GCD and OperationsThe GCD HandbookGCDModernize libdispatch for Swift 3 naming conventionsGCDGCD â BetaCONCURRENCY IN IOSwww.uraimo.com/2017/05/07/all-about-concurrency-in-swift-1-the-presentAll about concurrency in Swift â Part 1: The Present