使用NSDictionary线程安全崩溃?

时间:2012-07-06 14:21:44

标签: ios thread-safety 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以捕获更新。

但是,访问EXC_BAD_ACCESS时偶尔会发生_itemFlagDict崩溃,这让我相信在访问objectForKey:itemID时会重新分配字典。

我尝试的另一种方法是在访问器和setter方法上使用@synchronized(_itemFlagDict)。虽然这解决了这个问题,但这段代码对性能敏感,同步访问/分配导致性能下降太多。

所以我的问题是,我是否可以使用其他模式/方法来避免这种不良访问而不影响性能?如果优先级很重要,那么访问器方法的执行(并不一定是铁质精确度)是最重要的。

注意:我正在使用iOS 4及以上版本

2 个答案:

答案 0 :(得分:0)

您是否尝试过读/写锁?您可以在get方法中使用多个线程,在set方法https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/pthread.3.html

中使用一个编写器

答案 1 :(得分:0)

我遇到了同样的问题,我目前的解决方案是使用Atomic操作来实现一个线程安全的字典。 你可以查看它:https://github.com/bangquangvn/FastestThreadsafeDictionary-iOS

我认为这是最快的解决方案。