Objective-C 中的弱键字典
我想知道是否可能有类似于 ActionScript 3 的 Dictionary
对象的东西,在 Objective-C 中具有弱键。 我希望能够将类的实例“附加”到其他任意实例。
例子;
MetaData *meta = [MetaData metaDataForObject:someObject];
meta.whatever = foo;
后来:
foo = [MetaData metaDataForObject:someObject].whatever;
[foo doStuff];
棘手的部分是,在 someObject
引用的对象被释放后,我希望释放 meta
引用的对象(并释放,假设没有客户端代码保留它)。
可能的? 我看了一下 +[NSValue valueWithNonretainedObject:]
但我不确定这是否是我想要的,因为当我稍后查询 -[NSValue nonretainedObjectValue]
时,它似乎就像我会得到一个指向垃圾的指针(当对象被释放时,NSValue 如何将指针归零?)。
谢谢,
benjamin
2011 年 9 月 23 日更新:我相信实现此目的的方法是使用 objc_setAssociatedObject
和相关函数。 请参阅 Objective-C 运行时参考。
I'm wondering if it's possible to have something similar to ActionScript 3's Dictionary
object with weak keys in Objective-C. I want to be able to 'attach' an instance of a class to other arbitrary instances.
Example;
MetaData *meta = [MetaData metaDataForObject:someObject];
meta.whatever = foo;
And later:
foo = [MetaData metaDataForObject:someObject].whatever;
[foo doStuff];
The tricky part is that after the objected referenced by someObject
is dealloc'd, I want the object referenced by meta
to be released (and dealloc'd, assuming no client code has retained it).
Possible? I took a look at +[NSValue valueWithNonretainedObject:]
but I'm not sure if this is what I want because there when I later query -[NSValue nonretainedObjectValue]
it seems like I would get a pointer to garbage (how could NSValue zero the pointer when the object was dealloc'd?).
Thanks,
benjamin
Update 23 September 2011: I believe the way to do this is with objc_setAssociatedObject
and related functions. See the Objective-C Runtime Reference.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
听起来您所要求的是能够对被释放的弱引用实例变量做出反应。 您当然可以使用 __weak 属性(启用 GC)来创建弱引用,但是没有内置机制来捕获此类属性在其目标被 GC 后归零的情况。
如果你真的想要这个,最好的选择是使用 Apple 的 Key-Value Observing 使用的相同机制:方法调配。 维护一个将对象映射到其相应元数据对象的全局表(例如
NSHashMap
或NSMapTable
),然后替换dealloc
/finalize您要附加的对象的类中的
方法,其版本在表中查找相应的元数据对象并发送消息以将其拆除。 (您还需要另一个或两个表将类映射到其原始dealloc
/finalize
方法。) JRSwizzle 提供了一个很好的 swizzling 界面。如果你想要真正的花哨,而不是覆盖目标类的所有对象的dealloc/finalize,你可以创建一个代理类并重新分配
isa
指针仅用于该类,这样对于您不观看的对象的释放不会影响性能。 (KVO 也这样做。)It sounds like what you're asking for is the ability to react to a weak-referenced instance variable being deallocated. You can certainly use the
__weak
attribute (with GC enabled) to create a weak reference, but there's no built-in mechanism to catch when such an attribute is zeroed after its target is GCed.If you really want this, your best bet is to use the same mechanism Apple's Key-Value Observing uses: method swizzling. Maintain a global table (such as a
NSHashMap
orNSMapTable
) mapping objects to their corresponding metadata objects, then replace thedealloc
/finalize
methods in the class of the object you're attaching to with versions that look up the corresponding metadata object in the table and send a message to tear it down. (You also need another table or two that maps classes to their originaldealloc
/finalize
methods.) JRSwizzle provides a nice interface to swizzling.If you want to to be really fancy, instead of overwriting the
dealloc
/finalize
for all objects of the target class, you can create a proxy class and reassign theisa
pointer for just that class, such that there's no performance hit on deallocation for the objects you're not watching. (KVO does this, too.)您是否在寻找 NSHashMap ? 它会将引用归零。
Are you looking for NSHashMap perhaps? It does zeroing references.