Потокобезопасность NSMutableDictionary

У меня есть вопрос на потокобезопасности при использовании NSMutableDictionary.

Основной поток считывает данные с NSMutableDictionary где:

  • ключ NSString
  • значение UIImage

Асинхронный поток пишет данные в вышеупомянутый словарь (использование NSOperationQueue)

Как я делаю вышеупомянутый словарь ориентированным на многопотоковое исполнение?

Если я делаю NSMutableDictionary свойство atomic? Или я должен внести какие-либо дополнительные изменения?

@property(retain) NSMutableDictionary *dicNamesWithPhotos;

39
задан Stunner 6 March 2014 в 23:34
поделиться

1 ответ

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, которая является многопоточной безопасной библиотекой. Лично я его не использовал, и кажется, что это библиотека в процессе работы, но вы можете попробовать.

.
73
ответ дан 27 November 2019 в 02:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: