Raj*_*Raj 39 objective-c nsmutabledictionary
我在使用时有一个关于线程安全的问题NSMutableDictionary
.
主线程是从以下NSMutableDictionary
位置读取数据:
NSString
UIImage
异步线程正在将数据写入上面的字典(使用NSOperationQueue
)
如何使上面的字典线程安全?
我应该做的NSMutableDictionary
财产atomic
?或者我是否需要进行任何其他更改?
@property(retain) NSMutableDictionary *dicNamesWithPhotos;
not*_*oop 73
NSMutableDictionary
不是设计为线程安全的数据结构,只是将属性标记为atomic
,不能确保基础数据操作实际上是以原子方式(以安全的方式)执行的.
为确保每个操作都以安全的方式完成,您需要使用锁来保护字典上的每个操作:
// 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];
Run Code Online (Sandbox Code Playgroud)
您应该考虑滚动自己NSDictionary
,只需在持有锁的情况下将调用委托给NSMutableDictionary:
@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
Run Code Online (Sandbox Code Playgroud)
请注意,因为每个操作都需要等待锁定并持有它,所以它不是很可扩展,但在你的情况下它可能已经足够了.
如果要使用正确的线程库,可以使用TransactionKit库,因为它们TKMutableDictionary
是一个多线程安全库.我个人还没有使用它,它似乎是一个正在进行中的工作库,但你可能想尝试一下.
现在你可能会去@synchronized(object)
。
...
@synchronized(dictionary) {
[dictionary setObject:image forKey:name];
}
...
@synchronized(dictionary) {
[dictionary objectForKey:key];
}
...
@synchronized(dictionary) {
[dictionary removeObjectForKey:key];
}
Run Code Online (Sandbox Code Playgroud)
不再需要NSLock
对象