【问题标题】:Having a list of unretained id objects?有未保留的 id 对象列表?
【发布时间】:2012-08-09 08:28:51
【问题描述】:

如何实现一个类/对象,它引用了一堆非保留的id 对象?

我想要类似于 UIControl/NSControl 的东西:addTarget:(id)target action:(SEL)action ...;(不过,在我的情况下,我不需要 UIControlEvents 部分)。我想使用这个目标/动作模式(最好远离委托模式),但为此我需要确保添加到我的对象的目标不会被保留,否则可能会发生保留循环。

我认为使用malloc/free 实现我自己的数组以确保不保留目标将是一种解决方案,但所有这些麻烦听起来好像已经在某处实施了解决方案。有吗?

【问题讨论】:

  • malloc?您可以简单地使用std::vector,或std::list,或...

标签: cocoa-touch cocoa memory-management collections


【解决方案1】:

在 OS X 上,您可以创建一个 NSPointerArray,它会使用 +[NSPointerArray weakObjectsPointerArray] 保持对其对象的弱引用,或者(如果您想要一个字典)一个 NSMapTable,它允许键和值中的一个或两个虚弱地握住。

目前在 iOS 上两者都不可用,但 Core Foundation 是可用的。在 OS X 或 iOS 上,您可以使用 CFArrayCFDictionary,将 NULL 传递给回调以使集合不对其包含的对象进行内存管理。请注意,如果您尝试使用它们,就好像它们是免费的桥接 Cocoa 对应物一样,该集合将不会满足您不保留/不复制的愿望。您必须使用 CF 函数与它们进行交互(或创建一个包装类)。

您还可以使用valueWithNonretainedObject: 将对象包装在NSValues 中,然后将它们放入Cocoa 集合中(NSDictionary/NSarray)。集合将拥有该值,但该值将不拥有其对象。

【讨论】:

  • 我会给予更多的分数,但在▲ 中只允许单击 1 次。这效果很好!
  • 由于我在 iOS 中,NSPointerArray 被丢弃(我想这是已经/尚未移植到 iOS 的类之一)。我也想到了CFArray,但正如你指出的那样,免费桥接电话可能会变得有点麻烦,所以我使用了[NSValue valueWithNonretainedObject:],它就像一个魅力:)
【解决方案2】:

你可以创建一个CFArrayRef,指定不执行引用计数操作的回调(或者如果你觉得很懒,回调只为0):

CFAllocatorRef allocator = 0;
const void **values = ...;
CFIndex numValues = ...;
const CFArrayCallBacks* const callBacks = 0;

CFArrayRef arr = CFArrayCreate(allocator, values, numValues, callBacks);

【讨论】:

    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多