Ios 使用NSDictionary的线程安全崩溃?
我在多个线程中多次访问和设置NSDictionary,如下所示:Ios 使用NSDictionary的线程安全崩溃?,ios,thread-safety,nsdictionary,Ios,Thread Safety,Nsdictionary,我在多个线程中多次访问和设置NSDictionary,如下所示: - (BOOL)flagForItem:(NSNumber*)itemID { if(itemID) { return [[_itemFlagDict objectForKey:itemID] boolValue] } return NO; } 以及: 在set方法中,我最初有一个NSMutableDictionary——它被更改为您现在看到的模式,因为,doh,NSMutableDi
- (BOOL)flagForItem:(NSNumber*)itemID
{
if(itemID) {
return [[_itemFlagDict objectForKey:itemID] boolValue]
}
return NO;
}
以及:
在set方法中,我最初有一个NSMutableDictionary——它被更改为您现在看到的模式,因为,doh,NSMutableDictionary不是线程安全的。我的理由是在副本中执行变异,然后重新分配\u itemFlagDict
以捕获更新
但是,在访问\u itemFlagDict
时,偶尔仍会发生EXC\u BAD\u ACCESS
崩溃,这使我相信,在访问objectForKey:itemID
时,字典被重新分配了
我尝试的另一种方法是在accessor和setter方法上使用@synchronized(_itemFlagDict)
。虽然这解决了问题,但此代码对性能非常敏感,同步访问/分配会导致太多性能下降
所以我的问题是,我是否可以使用其他模式/方法来避免这种糟糕的访问,同时又不影响性能?如果优先级很重要,那么访问器方法的执行(不一定是铁板一块的准确性)是最重要的
注意:我正在使用iOS 4及以上版本您尝试过读/写锁吗?get方法中可以有多个线程,set方法中可以有一个writer。我遇到了同样的问题,我当前的解决方案是使用原子操作实现线程安全字典。 您可以查看它:
我认为这是最快的解决方案。看看这个答案,这是一个很好的例子,但我以前见过它,我认为它的问题是它会锁定字典上正在执行的任何选择器,我不希望这样,因为读和写都会阻塞,这会降低性能。您尝试过读/写锁定吗?get方法中可以有多个线程,set方法中可以有一个writer。
- (void)setFlagForItem:(NSNumber*)itemID
{
if(itemID) {
NSMutableDictionary *copy = [_itemFlagDict mutableCopy];
[copy setObject:[NSNumber numberWithBool:YES] forKey:itemID];
_itemFlagDict = [NSDictionary dictionaryWithDictionary:copy];
}
}