If I try to use a dispatch_source_t as the key in an NSMutableDictionary:
dispatch_source_t source = dispatch_source_create(stuff...);
NSMutableDictionary filesAndSources = [NSMutableDictionary dictionary];
filesAndSources[source] = @{stuff goes here};
I get the warning:
Sending 'dispatch_source_t' (aka 'NSObject<OS_dispatch_source> *') to parameter of incompatible type 'id<NSCopying> _Nonnull'
I assume it's because a dispatch_source_t doesn't use the NSCopying protocol. My solution was to stuff the dispatch_source_t into an NSValue:
NSValue* val = [NSValue valueWithPointer:(__bridge const void* _Nullable)(source)];
filesAndSources[val] = @{stuff};
This quiets the warning, but I'm not sure if that's the right way to pass a dispatch_source_t around.
Take a look at NSMapTable
which has finer control of key and value semantics than NS(Mutable)Dictionary
.
Pointer equality, NSMapTableObjectPointerPersonality
, can be specified for the keys rather than requiring they conform to NSCopying
and provide isEqual:
and hash
can be specified for the keys; while still using strong references to the values, NSMapTableStrongMemory
, creating a table with:
[NSMapTable mapTableWithKeyOptions: NSMapTableObjectPointerPersonality
valueOptions:NSMapTableStrongMemory]
Instance methods are objectForKey:
and setObject:forKey:
et al, but you don't get the get/set indexing syntax shorthands available with NS(Mutable)Dictionary
.