Ios 使用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

我在多个线程中多次访问和设置NSDictionary,如下所示:

- (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];
    }
}