保留核心基金会财产

时间:2012-02-14 09:23:29

标签: objective-c ios automatic-ref-counting core-foundation

(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?

2 个答案:

答案 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对象指针(idClassNSFoo*等。)
  •   
  • 标有__attribute__((NSObject))
  • 的typedef   

(强调我添加的最后一项)

所以如果你创建一个这样的typedef:

typedef __attribute__((NSObject)) CGImageRef MyImageRef;

并声明你的财产:

@property (nonatomic, strong) MyImageRef loupeImage;

底层变量将由ARC管理(因为底层变量将具有typedef' d类型,这是一种ARC管理类型),您不必在{{{ 1}}。