NSMutableDictionary线程安全 [英] NSMutableDictionary thread safety
问题描述
使用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屋!