在 NSMutableDictionary 中存储 dispatch_source_t

Storing a dispatch_source_t in an 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 的正确方法。

如果您只想使用调度源对象引用作为字典的键,并且您知道用作键的所有对象都存在并且有效(这是一个重要的要求),那么你可以只使用指针值作为整数键:

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

这是因为对象一旦创建就不会移动,因此对象引用的整数表示在该对象的生命周期内将是一个常量。只需确保在销毁对象之前删除该条目,否则您可能会得到重复的键。

看看 NSMapTable,它比 NS(Mutable)Dictionary 对键和值语义的控制更好。

可以为键指定指针相等,NSMapTableObjectPointerPersonality而不是要求它们符合NSCopying并提供isEqual:并且可以为键指定hash ;在仍然使用对值 NSMapTableStrongMemory 的强引用的同时,创建一个 table with:

[NSMapTable mapTableWithKeyOptions: NSMapTableObjectPointerPersonality
                      valueOptions:NSMapTableStrongMemory]

实例方法是 objectForKey:setObject:forKey: ,但您没有使用 get/set 索引语法简写 NS(Mutable)Dictionary.