我想要一个由强引用支持但在ARC中具有Core Foundation对象类型(不是Objective-C对象类型)的属性。我认为正确的方法是用__attribute__((NSObject))
标记它,ARC将像Objective-C对象类型属性一样管理它(即释放并保留在assign,并在包含对象为{{1时释放) }} ED):
dealloc
(我知道@interface Foo : NSObject
@property (nonatomic, strong) __attribute__((NSObject)) CFArrayRef bar;
@end
@implementation Foo
// property bar is auto-synthesized
@end
是免费的桥接到CFArray
。这仅仅是为了一个例子。真正的用例是针对没有免费电话的Core Foundation类型桥接。)
但是当我将一个对象放入NSArray
对象的bar
属性并让Foo
对象超出范围并得到Foo
时,该对象就在dealloc
被泄露,因为在bar
对象被释放时它没有被释放,就像使用常规的Objective-C对象类型属性一样:
Foo
代码编译时没有任何警告或错误,并且没有任何问题地通过Analyze。 Leaks仪器检测到可变阵列泄漏。
这是编译器错误吗?我正在使用最新的Xcode(8.3.3)。
答案 0 :(得分:2)
ARC specification中有一些好奇的措辞,当定义可保留对象指针时,最后一种被定义为:
标有
的typedef__attribute__((NSObject))
请注意,这使用 typdefs 而不是声明。在规范中再次使用措辞。这个几乎似乎建议您需要使用typedef
来识别属性,这将是一个奇怪的设计。
不幸的是,当谈到财产声明时,规范说(重点补充):
将
__attribute__((NSObject))
应用于不属于可保留对象指针类型的属性与ARC之外的属性相同:它要求属性类型为某种指针并允许使用除{{1之外的修饰符}}。这些修饰符只影响合成的吸气剂和固定剂;对ivar的直接访问(即使合成)仍然具有原始语义,并且在重新分配期间不会自动释放ivar中的值。
这似乎可以解释你所看到的行为 - 设计是半生不熟的,getter / setter采用语义,但是deallocation没有。
鉴于规范措辞你对自动支持的希望似乎是首先为CF类型创建一个属性typedef,然后在属性声明中使用它...如果是真的很奇怪,但它符合好奇的措辞......对不起目前无法检查这一点,但我猜测结果会令人失望。尝试将assign
分配给nil
中的属性,因为它使用的setter(根据规范)具有正确的语义。
HTH