這個應該是全平臺都會遇到的問題了。當某個對象會被多個線程修改的時候,有可能一個線程訪問這個對象的時候另外一個線程已經把它刪掉了,致使 Crash。比較常見的是在網絡任務隊列裏面,主線程往隊列裏面加入任務,網絡線程同時進行刪除操做致使掛掉。html
這個真要寫比較完整的併發操做的例子就有點複雜了。shell
普通的鎖,加鎖的時候 lock,解鎖調用 unlock。網絡
- (void)addPlayer:(Player *)player { if (player == nil) return; NSLock* aLock = [[NSLock alloc] init]; [aLock lock]; [players addObject:player]; [aLock unlock]; } }
能夠使用標記符 @synchronized 簡化代碼:多線程
- (void)addPlayer:(Player *)player { if (player == nil) return; @synchronized(players) { [players addObject:player]; } }
使用普通的 NSLock 若是在遞歸的狀況下或者重複加鎖的狀況下,本身跟本身搶資源致使死鎖。Cocoa 提供了 NSRecursiveLock 鎖能夠屢次加鎖而不會死鎖,只要 unlock 次數跟 lock 次數同樣就好了。併發
多數狀況下鎖是不須要關心什麼條件下 unlock 的,要用的時候鎖上,用完了就 unlock 就完了。Cocoa 提供這種條件鎖,能夠在知足某種條件下才解鎖。這個鎖的 lock 和 unlock, lockWhenCondition 是隨意組合的,能夠不用對應起來。分佈式
這是用在多進程之間共享資源的鎖,對 iOS 來講暫時沒用處。線程
無鎖
放棄加鎖,採用原子操做,編寫無鎖隊列解決多線程同步的問題。酷殼有篇介紹無鎖隊列的文章能夠參考一下:無鎖隊列的實現code