Objective-C 中的弱键字典

发布于 2024-07-16 11:10:12 字数 990 浏览 7 评论 0原文

我想知道是否可能有类似于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好多鱼好多余 2024-07-23 11:10:12

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

如果你真的想要这个,最好的选择是使用 Apple 的 Key-Value Observing 使用的相同机制:方法调配。 维护一个将对象映射到其相应元数据对象的全局表(例如 NSHashMapNSMapTable),然后替换 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 or NSMapTable) mapping objects to their corresponding metadata objects, then replace the dealloc/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 original dealloc/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 the isa 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.)

浅唱々樱花落 2024-07-23 11:10:12

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

Are you looking for NSHashMap perhaps? It does zeroing references.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文