__attribute __((NSObject))自动合成属性不会在dealloc中释放

时间:2017-09-01 04:19:23

标签: objective-c memory-leaks properties automatic-ref-counting core-foundation

我想要一个由强引用支持但在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)。

1 个答案:

答案 0 :(得分:2)

ARC specification中有一些好奇的措辞,当定义可保留对象指针时,最后一种被定义为:

  

标有__attribute__((NSObject))

的typedef

请注意,这使用 typdefs 而不是声明。在规范中再次使用措辞。这个几乎似乎建议您需要使用typedef来识别属性,这将是一个奇怪的设计。

不幸的是,当谈到财产声明时,规范说(重点补充):

  

__attribute__((NSObject))应用于不属于可保留对象指针类型的属性与ARC之外的属性相同:它要求属性类型为某种指针并允许使用除{{1之外的修饰符}}。这些修饰符只影响合成的吸气剂和固定剂;对ivar的直接访问(即使合成)仍然具有原始语义,并且在重新分配期间不会自动释放ivar中的值

这似乎可以解释你所看到的行为 - 设计是半生不熟的,getter / setter采用语义,但是deallocation没有。

鉴于规范措辞你对自动支持的希望似乎是首先为CF类型创建一个属性typedef,然后在属性声明中使用它...如果是真的很奇怪,但它符合好奇的措辞......对不起目前无法检查这一点,但我猜测结果会令人失望。尝试将assign分配给nil中的属性,因为它使用的setter(根据规范)具有正确的语义。

HTH