首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSMutableDictionary线程安全

NSMutableDictionary线程安全
EN

Stack Overflow用户
提问于 2009-12-31 19:16:18
回答 5查看 28.7K关注 0票数 44

在使用NSMutableDictionary时,我有一个关于线程安全的问题。

主要线程是从NSMutableDictionary读取数据,其中:

  • 密钥是NSString
  • 值为UIImage

异步线程正在将数据写入上述字典(使用NSOperationQueue)。

如何使上述字典线程安全?

我应该做NSMutableDictionary属性atomic吗?还是我需要做任何额外的改变?

@property(retain) NSMutableDictionary *dicNamesWithPhotos;

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-12-31 19:52:22

NSMutableDictionary不是设计为线程安全的数据结构,只是将属性标记为atomic,并不能确保底层数据操作实际上是以一种安全的方式执行的。

为了确保每个操作都以安全的方式完成,您需要使用锁来保护字典上的每个操作:

代码语言:javascript
复制
// in initialization
self.dictionary = [[NSMutableDictionary alloc] init];
// create a lock object for the dictionary
self.dictionary_lock = [[NSLock alloc] init];


// at every access or modification:
[object.dictionary_lock lock];
[object.dictionary setObject:image forKey:name];
[object.dictionary_lock unlock];

您应该考虑滚动您自己的NSDictionary,它只需在持有锁时将调用委托给NSMutableDictionary:

代码语言:javascript
复制
@interface SafeMutableDictionary : NSMutableDictionary
{
    NSLock *lock;
    NSMutableDictionary *underlyingDictionary;
}

@end

@implementation SafeMutableDictionary

- (id)init
{
    if (self = [super init]) {
        lock = [[NSLock alloc] init];
        underlyingDictionary = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (void) dealloc
{
   [lock_ release];
   [underlyingDictionary release];
   [super dealloc];
}

// forward all the calls with the lock held
- (retval_t) forward: (SEL) sel : (arglist_t) args
{
    [lock lock];
    @try {
        return [underlyingDictionary performv:sel : args];
    }
    @finally {
        [lock unlock];
    }
}

@end

请注意,因为每个操作都需要等待锁并保存它,所以它不是完全可伸缩的,但在您的情况下可能足够好。

如果您想使用适当的线程库,可以使用TransactionKit库,因为它们具有TKMutableDictionary,这是一个多线程安全库。我个人还没有使用过它,而且它似乎是一个正在进行的工作库,但是您可能需要尝试一下。

票数 78
EN

Stack Overflow用户

发布于 2018-08-02 09:04:01

现在,你可能会转而选择@synchronized(object)

代码语言:javascript
复制
...
@synchronized(dictionary) {
    [dictionary setObject:image forKey:name];
}
...
@synchronized(dictionary) {
    [dictionary objectForKey:key];
}
...
@synchronized(dictionary) {
    [dictionary removeObjectForKey:key];
}

不再需要NSLock对象了

票数 6
EN

Stack Overflow用户

发布于 2011-05-06 19:52:49

经过一些研究之后,我想和大家分享这篇文章:

在多线程应用程序http://developer.apple.com/library/mac/#technotes/tn2002/tn2059.html中安全地使用集合类

看来,这个问题的答案可能根本不是解决办法。从线程的角度来看,这是可以的,但也有一些关键的微妙之处。我不会在这里发布解决方案,但我想本文中有一个很好的解决方案。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1986736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档