Хранение 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};
Это потому, что объекты не перемещаются после создания, поэтому целочисленное представление ссылки на объект будет константой в течение всего времени жизни этого объекта. Просто убедитесь, что вы удалили запись, прежде чем уничтожить объект, иначе вы можете получить дубликаты ключей.