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 使用的相同机制:方法调配。维护一个全局表(例如 NSHashMap
或 NSMapTable
)将对象映射到其相应的元数据对象,然后将您附加到的对象类中的 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 中的弱键字典的主要内容,如果未能解决你的问题,请参考以下文章
搞定 WeakHashMap 的工作原理一篇文章就够了!!!