【发布时间】:2012-07-21 17:26:01
【问题描述】:
是否可以向使用运行时创建的类添加归零弱引用(在 ARC 意义上,而不是 GC)实例变量?如果有怎么办?
有一个名为class_setWeakIvarLayout() 的函数似乎与此相关,但不幸的是,文档(对于此函数和非弱对应项)非常很薄。
【问题讨论】:
标签: objective-c automatic-ref-counting weak-references objective-c-runtime
是否可以向使用运行时创建的类添加归零弱引用(在 ARC 意义上,而不是 GC)实例变量?如果有怎么办?
有一个名为class_setWeakIvarLayout() 的函数似乎与此相关,但不幸的是,文档(对于此函数和非弱对应项)非常很薄。
【问题讨论】:
标签: objective-c automatic-ref-counting weak-references objective-c-runtime
您可以使用具有容器类的关联引用来实现归零弱引用。基本上:
__weak id
__weak id ivar 设置为指向您的对象,然后使用objc_setAssociatedObjects(self,&key,container,OBJC_ASSOCIATION_RETAIN) 存储容器
objc_getAssociatedObject(self, &key) 检索容器并返回 __weak id ivar。如果您的对象已被dealloc'ed,则容器的__weak id ivar 将为零。【讨论】:
OBJC_ASSOCIATION_RETAIN 不应该是 OBJC_ASSOCIATION_ASSIGN 吗?
class_setWeakIvarLayout() 在 GC 下使用。我不确定它是否在 ARC 下使用。在任何情况下,您都无法在运行时更改类的布局,包括添加任意实例变量(尽管由于现代运行时,您可以将 ivars 添加到类并重新编译而无需重新编译子类)。
请参阅关联对象。它们提供了您想要的大部分,也许是全部(我不确定是否直接支持 zeroing-weak - 不,您需要找到替代解决方案)。
啊——好的。感谢您的澄清。我不确定您是否可以通过 API 动态设置弱调零 ARC 行为。不过,运行时和编译器的源代码是可用的。
请注意,您可以很容易地在非 ARC 环境下伪造归零弱,方法是设置一个实现 -dealloc 的类来执行您需要的任何清理,将实例与需要在释放时触发所述清理的对象相关联,并确保没有别的保留具有自定义 -dealloc 通知挂钩的对象。它有点脆弱,但它可以工作。
【讨论】: