我有代碼訪問,並在多個線程設置一個NSDictionary很多次,像這樣:使用NSDictionary線程安全崩潰?
- (BOOL)flagForItem:(NSNumber*)itemID
{
if(itemID) {
return [[_itemFlagDict objectForKey:itemID] boolValue]
}
return NO;
}
和:
- (void)setFlagForItem:(NSNumber*)itemID
{
if(itemID) {
NSMutableDictionary *copy = [_itemFlagDict mutableCopy];
[copy setObject:[NSNumber numberWithBool:YES] forKey:itemID];
_itemFlagDict = [NSDictionary dictionaryWithDictionary:copy];
}
}
在set方法,我本來有一個的NSMutableDictionary - 這被改爲你現在看到的模式是因爲doh,NSMutableDictionary不是線程安全的。我的推理是在副本中執行突變,然後重新指定_itemFlagDict
以捕獲更新。
但是,在訪問_itemFlagDict
時,偶爾會發生一個EXC_BAD_ACCESS
崩潰,導致我相信字典在訪問objectForKey:itemID
時被重新分配。
我試過的另一種方法是在訪問器和setter方法上都使用@synchronized(_itemFlagDict)
。雖然這解決了這個問題,但該代碼對性能非常敏感,並且同步訪問/分配會導致性能下降太多。
所以我的問題是,有沒有其他模式/方法可以用來避免這種不良訪問,同時不影響性能?如果優先級重要,訪問方法的執行(不一定是鐵精確度)是最重要的。
注意:我正在使用iOS 4及以上版本
看看這個答案http://stackoverflow.com/questions/1986736/nsmutabledictionary-thread-safety – MrShoot 2012-07-07 04:57:22
這是一個很好的例子,但我見過它之前,我認爲它的問題是,它鎖定任何選擇器正在字典上執行,我不希望自讀取將阻止以及寫入,這會降低性能 – Dfowj 2012-07-09 17:28:26
你試過讀/寫鎖嗎?您可以在get方法中使用多個線程,並在set方法中使用一個寫入器。 https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/pthread.3.html – Ali 2013-03-07 20:19:33