У меня есть вопрос на потокобезопасности при использовании NSMutableDictionary
.
Основной поток считывает данные с NSMutableDictionary
где:
NSString
UIImage
Асинхронный поток пишет данные в вышеупомянутый словарь (использование NSOperationQueue
)
Как я делаю вышеупомянутый словарь ориентированным на многопотоковое исполнение?
Если я делаю NSMutableDictionary
свойство atomic
? Или я должен внести какие-либо дополнительные изменения?
@property(retain) NSMutableDictionary *dicNamesWithPhotos;
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];
Вам следует рассмотреть возможность прокатки собственного NSD словаря
, который просто делегирует вызовы в 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
Пожалуйста, обратите внимание, что поскольку каждая операция требует ожидания блокировки и удержания ее, она не совсем масштабируема, но может быть достаточно хороша в вашем случае.
Если вы хотите использовать подходящую потоковую библиотеку, вы можете использовать Библиотеку TransactionKit, так как у них есть TKMutableDictionary
, которая является многопоточной безопасной библиотекой. Лично я его не использовал, и кажется, что это библиотека в процессе работы, но вы можете попробовать.