(Xcode 4.2,iOS 5, ARC )
我有一些Core Foundation(/ Graphics)对象的属性,它们应该拥有对象的所有权。现在在这些Apple docs我发现了这个:
在OS X v10.6及更高版本中,您可以使用__attribute__关键字指定Core Foundation属性应被视为 用于内存管理的Objective-C对象:
@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;
不幸的是我找不到任何详细说明。我正在使用这个:
@property (nonatomic, strong) __attribute__((NSObject)) CGImageRef loupeImage;
它似乎按我期望的方式工作。它保留了设置属性的对象,并在将属性设置为nil时将其释放。
现在我的问题是,我是否还需要在我的dealloc中将这些属性显式设置为nil?
答案 0 :(得分:15)
编辑:我以前的帖子不正确。属性上的__attribute__((NSObject))
仅使其在使用属性访问器时保留/释放属性。它不会影响对ivar的访问,值得注意的是,它不会在dealloc
中删除(或释放)该属性。是的,在您的dealloc
中,您需要说self.loupeImage = nil;
或者您需要说[_loupeImage release]
。
原帖:
如果编译器接受strong
关键字,那么它将正确处理它,保留并按预期释放,并在ARC中自动终止。 __attribute__((NSObject))
的整个想法是它告诉编译器将这个对象看作是一个obj-c对象,这就是它的作用。
所以不,你不应该在dealloc中明确地将它们取出来。您将自动获得nilling / release的默认ARC行为。
答案 1 :(得分:1)
现在我的问题是,我是否仍需要明确设置这些属性 在我的dealloc中没有?
是,您所做的声明就是这样。
在ARC规范的Property declarations section中,它说:
将
__attribute__((NSObject))
应用于不可保留的属性 对象指针类型与ARC之外的行为相同:它 要求属性类型是某种指针并允许 使用assign
以外的修饰符。这些修饰符只影响 合成吸气剂和定位剂;直接进入伊达(即使 合成的)仍然具有原始语义,并且中的值 在解除分配期间不会自动释放ivar 。
(强调最后一部分由我添加)
换句话说,在具有Core Foundation类型的属性上应用__attribute__((NSObject))
和strong
会使getter和setter正常工作,但它不会使ARC管理底层实例变量(因为实例变量& #39; s类型仍然是Core Foundation类型),因此如果它是非零,ARC将不会在dealloc
上释放实例变量。使用这样的属性声明,您必须在dealloc
中将其取消或导致泄漏。
但是,有一种方法可以让ARC自己管理变量。由于该变量具有Core Foundation类型,因此您可以将其包含在typedef
__attribute__((NSObject))
的{{1}}中,从而使其成为ARC管理类型。
ARC规范的Retainable object pointers section说:
有三种可保留对象指针类型:
- 块指针(通过应用插入符(
^
)声明符形成 sigil to a function type)- Objective-C对象指针(
id
,Class
,NSFoo*
等。)- 标有
的typedef__attribute__((NSObject))
(强调我添加的最后一项)
所以如果你创建一个这样的typedef:
typedef __attribute__((NSObject)) CGImageRef MyImageRef;
并声明你的财产:
@property (nonatomic, strong) MyImageRef loupeImage;
底层变量将由ARC管理(因为底层变量将具有typedef
' d类型,这是一种ARC管理类型),您不必在{{{ 1}}。