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 inversion
deadlock
-è€æ°ã®ã¹ã¬ãããããããã®ã¹ã¬ããèªäœãå æãããªãœãŒã¹ãç¡éã«åŸ
æ©ããŠãããã«ãã¹ã¬ããã·ã¹ãã ã®ç¶æ³
ç«¶åç¶æ
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
ãPlayground
cã³ãã³ãã§äœããã®ã€ãã³ããåŸ
ã€ã®ãæ¢ããããšãã§ã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æåãå°å·ããå¥ã®ã¿ã¹ã¯ãé«ãåªå
床ã§å®è¡ããŸããuserQueue
utilityQueue
backgroundQueue
concurrent queue
defautQueue

task
taskHIGH

2.第äºã®å®éšã¯ãã«é©çšãããŸãåæããã³éåæçã«ã°ããŒãã«ãã¥ãŒã«
ããšãã°ãã°ããŒãã«ãã¥ãŒãåãåã£ãããmethodã䜿çšããŠSYNCHRONOUSLYã«ããŸãã¯methodã䜿çšããŠASYNCHRONOUSLYã«userQueue
ã¿ã¹ã¯ãå®è¡ã§ããŸããåæå®è¡ã®å Žåããã¹ãŠã®ã¿ã¹ã¯ã次ã
ã«é çªã«éå§ãããæ¬¡ã®ã¿ã¹ã¯ãåã®ã¿ã¹ã¯ã®å®äºãæç¢ºã«åŸ
ã£ãŠããããšãããããŸããããã«ãæé©åãšããŠãå¯èœã§ããã°ãsync颿°ã¯çŸåšã®ã¹ã¬ããã§ã¯ããŒãºãããªã¬ãŒã§ããã°ããŒãã«ãã¥ãŒã®åªå
é äœã¯éèŠã§ã¯ãããŸãããããã¯ç§ãã¡ãèŠããã®ã§ããéåæå®è¡ã®å Žåãã¿ã¹ã¯ã®å®äºãšã°ããŒãã«ãã¥ãŒã®åªå
é äœãåŸ
ããã«ã¿ã¹ã¯ãéå§ããããšãããããŸããsync
async

sync
async


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
ãã¥ãŒã䜿çšããŠ
ãæåã«ãã®ãã¥ãŒã«ã¿ã¹ã¯ãéåæçã«é
眮ããæ¬¡ã«ã¿ã¹ã¯
ãã¥ãŒserialPriorityQueue1
c qos .userInitiated
ãã¥ãŒserialPriorityQueue2
c ã¿ã¹ã¯ã®qos .background
ãã«ãã¹ã¬ããå®è¡ããããã¿ã¹ã¯ã¯ããserialPriorityQueue1
é«ããµãŒãã¹å質ã®ãã¥ãŒã§å®è¡ãããããšãå€ããªããŸãqos: .userIniatated
ãããšãã°ã颿°ã䜿çšããŠããµãŒãã¹ã®å質ã倿Žããããšã«ãããä»»æã®ãã¥ãŒã§ã®ã¿ã¹ã¯ã®å®è¡ãDispatchQueue
æå®ã®æéé
å»¶ãããããšãã§ããŸããnow() + 0.1
asyncAfter
qos

5. 5çªç®ã®å®éšã¯ããã©ã€ããŒã䞊åïŒåæïŒãã¥ãŒã«é¢ãããã®ã§ãã
Private
parallelïŒ.concurrent
ïŒãã¥ãŒãåæåããã«ã¯ãPrivate queueãåæåãããšãã«attributes
çããåŒæ°ã®å€ã瀺ãã ãã§åå.concurrent
ã§ãããã®åŒæ°ãæå®ããªãå ŽåãPrivate
ãã¥ãŒã¯é 次ïŒ.serial
ïŒã«ãªããŸããåŒæ°qos
ãå¿
é ã§ã¯ãªããåé¡ãªãã¹ãããã§ããŸããåçã®ãµãŒãã¹å質ã䞊åãã¥ãŒã«å²ãåœãŠãã¿ã¹ã¯ãæåã«ãã®ãã¥ãŒã«éåæçã«é
眮ããŠãããæ°ãã䞊åãã¥ãŒã¯å®éã«äžŠåã§ããããã®äžã®ã¿ã¹ã¯ã¯åæã«å®è¡ãããŸããã4çªç®ã®å®éšïŒ1ã€ã®é 次åãworkerQueue
qos
.userInitiated


workerQueue
serialPriorityQueue
ïŒã圌ãã¯åŒæ°ãattributes
çããèšå®ããŸã.concurrent
ïŒ
çµµã¯1ã€ã®é£ç¶ãããã¥ãŒãšæ¯èŒããŠå®å
šã«ç°ãªããŸãããã®å Žåã¯ãã¹ãŠã®ã¿ã¹ã¯ã¯ãå³å¯ã«ããããå®è¡ããããã«æ¥ãé åºã§è¡ãããŠãããããŠããç§ãã¡ã®äžŠåïŒãã«ãã¹ã¬ããïŒãã¥ãŒworkerQueue
è€æ°ã®ã¹ã¬ããã«ãåå²ããã¿ã¹ã¯ãå®éã«äžŠè¡ããŠè¡ãããšãã§ããŸãããã€ãã®ã¯ãšã¹ããèšå·ã§
ãåŸã«ãã¥ãŒã«å
¥ãããããšããŠãworkerQueue
䞊åã¹ã¬ããã§ã¯é«éã§ããã¬ããã»äœ¿çšäžŠåPrivate
ç°ãªãåªå
é äœãæã€ãã¥ãŒïŒãã¹ãŠã®workerQueue1
C qos .userInitiated
ãã¹ãŠã®workerQueue2
C qos .background
ç°ãªãé
åãæãããšåããã¿ãŒã³Private
2åç®ã®å®éšã§ããŒã¹ãããŸãã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ã€ã§ããã¯ã©ã¹ãšãã®ã¡ãœãããããã³ã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã¡ãœããã䜿çšã§ããŸããGCD
GCD
DispatchWorkItem
notify (queue:, execute:)
DispatchQueue
async(execute workItem: DispatchWorkItem)
ãã¹ãã®æåã«æç€ºãããåé¡ã解決ããããã«-ãããã¯ãŒã¯ããã€ã¡ãŒãžãããŠã³ããŒãããŸãïŒç¹å®ã®ã¢ãã¬ã¹ã§ããããã¯ãŒã¯ãããããŒã¿ãååŸããããšã§æ§æãããã¯ã©ã¹ã®
ã€ã³ã¹ã¿ã³ã¹ã®åœ¢åŒã§åæã¿ã¹ã¯ã圢æããŸãã颿°ã䜿çšããŠããµãŒãã¹å質ã§äžŠåã°ããŒãã«ãã¥ãŒã§éåæãžã§ããå®è¡ããworkItem
DispatchWorlItem
data
imageURL
workItem
queue
qos: .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 : .userInitiated
qos : .background

usualString
safeString
asyncAfter (deadline: .now() + 0.0, qos: .userInteractive)

usualString
safeString
asyncAfter (deadline: .now() + 0.1, qos: .userInteractive)

usualString
safeString

ãããŠ
æéééã§ããã«ãã¹ã¬ããã®å²ãåœãŠãããå Žæ
ãããŠ
ç°ãªããã¥ãŒã§çºçãããã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