NSMutableDictionary线程安全 [英] NSMutableDictionary thread safety

查看:104
本文介绍了NSMutableDictionary线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用NSMutableDictionary时我对线程安全性有疑问.

I have a question on thread safety while using NSMutableDictionary.

主线程正在从NSMutableDictionary读取数据,其中:

The main thread is reading data from NSMutableDictionary where:

  • 键是NSString
  • 值是UIImage
  • key is NSString
  • value is UIImage

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

An asynchronous thread is writing data to above dictionary (using NSOperationQueue)

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

How do I make the above dictionary thread safe?

我应该将NSMutableDictionary属性设置为atomic吗?还是我需要进行其他任何更改?

Should I make the NSMutableDictionary property atomic? Or do I need to make any additional changes?

@property(retain) NSMutableDictionary *dicNamesWithPhotos;

推荐答案

NSMutableDictionary并非设计为线程安全的数据结构,仅将属性标记为atomic并不能确保基础数据操作实际上是原子地执行的(以一种安全的方式).

NSMutableDictionary isn't designed to be thread-safe data structure, and simply marking the property as atomic, doesn't ensure that the underlying data operations are actually performed atomically (in a safe manner).

为确保每个操作均以安全的方式进行,您需要使用锁保护字典上的每个操作:

To ensure that each operation is done in a safe manner, you would need to guard each operation on the dictionary with a lock:

// 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:

You should consider rolling your own NSDictionary that simply delegates calls to NSMutableDictionary while holding a lock:

@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

请注意,由于每个操作都需要等待并按住该锁,因此它的可伸缩性不是很好,但是对于您而言,这可能就足够了.

Please note that because each operation requires waiting for the lock and holding it, it's not quite scalable, but it might be good enough in your case.

如果要使用适当的线程库,则可以使用 TransactionKit库,因为它们具有TKMutableDictionary这是一个多线程安全库.我个人还没有使用过它,它似乎是一个正在开发中的库,但是您可能想尝试一下.

If you want to use a proper threaded library, you can use TransactionKit library as they have TKMutableDictionary which is a multi-threaded safe library. I personally haven't used it, and it seems that it's a work in progress library, but you might want to give it a try.

这篇关于NSMutableDictionary线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆