Хранение dispatch_source_t в NSMutableDictionary

Если я пытаюсь использовать dispatch_source_t в качестве ключа в NSMutableDictionary:

dispatch_source_t               source = dispatch_source_create(stuff...);
NSMutableDictionary             filesAndSources = [NSMutableDictionary dictionary];

filesAndSources[source] = @{stuff goes here};

Я получаю предупреждение:

Sending 'dispatch_source_t' (aka 'NSObject<OS_dispatch_source> *') to parameter of incompatible type 'id<NSCopying> _Nonnull'

Я предполагаю, что это потому, что dispatch_source_t не использует протокол NSCopying. Моим решением было заполнить dispatch_source_t в NSValue:

NSValue*          val = [NSValue valueWithPointer:(__bridge const void* _Nullable)(source)];
filesAndSources[val] = @{stuff};

Это успокаивает предупреждение, но я не уверен, что это правильный способ передать dispatch_source_t.

2 ответа

Решение

Взгляни на NSMapTable который лучше контролирует семантику ключа и значения, чем NS(Mutable)Dictionary,

Равенство указателей, NSMapTableObjectPointerPersonality, можно указать для ключей, а не требовать, чтобы они соответствовали NSCopying и предоставить isEqual: а также hash можно указать для ключей; все еще используя сильные ссылки на значения, NSMapTableStrongMemory, создав таблицу с:

[NSMapTable mapTableWithKeyOptions: NSMapTableObjectPointerPersonality
                      valueOptions:NSMapTableStrongMemory]

Методы экземпляра objectForKey: а также setObject:forKey: и т. д., но вы не получаете сокращений синтаксиса get / set, доступных с NS(Mutable)Dictionary,

Если вы просто хотите использовать ссылку на исходный объект диспетчеризации в качестве ключа в словаре и знаете, что все объекты, используемые в качестве ключей, существуют и являются действительными (это важное требование), то вы можете просто использовать значение указателя в качестве целочисленный ключ:

sources[ @( (intptr_t)source ) ] = @{stuff};

Это потому, что объекты не перемещаются после создания, поэтому целочисленное представление ссылки на объект будет константой в течение всего времени жизни этого объекта. Просто убедитесь, что вы удалили запись, прежде чем уничтожить объект, иначе вы можете получить дубликаты ключей.

Другие вопросы по тегам