Objective-C 中的弱键字典

Posted

技术标签:

【中文标题】Objective-C 中的弱键字典【英文标题】:Weak-keyed dictionary in Objective-C 【发布时间】:2009-04-09 19:17:21 【问题描述】:

我想知道是否有可能在 Objective-C 中拥有类似于 ActionScript 3 的 Dictionary 对象的弱键。我希望能够将一个类的实例“附加”到其他任意实例。

示例;

MetaData *meta = [MetaData metaDataForObject:someObject];
meta.whatever = foo;

后来:

foo = [MetaData metaDataForObject:someObject].whatever;
[foo doStuff];

棘手的部分是在someObject 引用的对象被dealloc'd 后,我希望meta 引用的对象被释放(并且dealloc'd,假设没有客户端代码保留它)。

可能吗?我看了一下+[NSValue valueWithNonretainedObject:],但我不确定这是否是我想要的,因为当我后来查询-[NSValue nonretainedObjectValue] 时,似乎我会得到一个指向垃圾的指针(当对象是解除分配?)。

谢谢,

本杰明

2011 年 9 月 23 日更新:我相信使用objc_setAssociatedObject 和相关函数可以做到这一点。请参阅Objective-C Runtime Reference。

【问题讨论】:

【参考方案1】:

听起来您要求的是对被释放的弱引用实例变量做出反应的能力。您当然可以使用 __weak 属性(启用 GC)来创建弱引用,但没有内置机制可以捕获此类属性在其目标被 GC 后归零时的情况。

如果你真的想要这个,最好的办法是使用 Apple 的 Key-Value Observing 使用的相同机制:方法调配。维护一个全局表(例如 NSHashMapNSMapTable)将对象映射到其相应的元数据对象,然后将您附加到的对象类中的 dealloc/finalize 方法替换为看起来up 表中相应的元数据对象并发送消息将其删除。 (您还需要另外一两个表,将类映射到它们原来的 dealloc/finalize 方法。)JRSwizzle 提供了一个很好的调配接口。

如果你想要真正的花哨,而不是覆盖目标类的所有对象的dealloc/finalize,你可以创建一个代理类并为该类重新分配isa指针,例如对于您未观看的对象,释放不会对性能造成影响。 (KVO 也这样做。)

【讨论】:

方法调配听起来很简单。您能否详细说明您提到的 isa-swizzling 技术?据我了解,这将使我能够有效地更改对象的类,从而提供 dealloc 的新实现,对吗? 另请注意,在 10.5 中,您可以使用一个函数,这在未来更可取:developer.apple.com/DOCUMENTATION/Cocoa/Reference/…【参考方案2】:

您在寻找NSHashMap 吗?它会将引用归零。

【讨论】:

我正在为 iPhone 开发,不幸的是 NSHashMap 似乎不可用。

以上是关于Objective-C 中的弱键字典的主要内容,如果未能解决你的问题,请参考以下文章

MonoTouch 中的弱事件模式

总是将 self 的弱引用传递到 ARC 中的块中?

搞定 WeakHashMap 的工作原理一篇文章就够了!!!

常见的弱口令字典1000~一石三鸟

如何/在哪里声明用于编写objective-c代码的接口、实现、程序格式中的实例变量?

在 Objective-C 中实现纯虚方法