【问题标题】:Why using autorelease when assigning a custom object to an instance variable with a setter?为什么在使用 setter 将自定义对象分配给实例变量时使用 autorelease?
【发布时间】:2013-04-09 12:04:05
【问题描述】:

我想将自定义对象分配给实例变量。

代码如下:
- MyController.h/.m

#import "CustomData.h"  
@interface MyViewController : NSViewController  
@property (retain) CustomData* theData;  

- (void)aRandomMethod; 

@end

@implementation MyViewController  
@synthetize theData;  

- (void)aRandomMethod {  

   NSData* rawData = [someOtherObject someOtherMethod];

   // option 1
   self.theData = [[CustomData alloc] initWithData:rawData];

   // option 2
   CustomData* _theData = [[Custom alloc] initWithData:rawData];

   // option 3
   self.theData = [[[CustomData alloc] initWithData:rawData] autorelease];

   // option 4
   theData = [[CustomData alloc] initWithData:rawData];

   // ... later code calls some methods on theData or _theData, not useful here.
 }
@end

在 Xcode 中运行分析功能时,它告诉我选项 1 和 2 存在“泄漏的对象未在稍后引用...”,但选项 3 和 4 没有。看来我需要autorelease使用 setter 时的自定义对象。我知道在方法中返回我们拥有的对象时需要使用autorelease

你能解释一下每个选项为什么是错还是对?谢谢。

【问题讨论】:

  • 您在每个选项行都缺少左大括号。

标签: objective-c macos memory-management


【解决方案1】:

选项 1 是错误的,因为您在该方法中 alloc'd 对象,因此该方法现在拥有该对象,因此需要 release 它。当您将它分配给一个属性时,retains 它并预计在它完成后release 它。

出于同样的原因,选项 2 是错误的。你取出了它的属性部分,但是因为你用alloc创建了这个对象,你有责任在那个方法中调用release

选项 3 是正确的,因为您在将其提供给属性之前已将其 autoreleased,因此该方法不再拥有它。请注意,如果您在此处使用 release,它将中断,因为它会在属性有机会 retain 它之前 release 它。

选项 4 可能是正确的;我假设它将它分配给一个 ivar。仅当您稍后在 dealloc 方法中手动释放 ivar 时才正确。不过,通常最好通过属性。否则,您将面临分配另一个值并忘记 release 现有值的风险。

【讨论】:

    【解决方案2】:

    选项 1 和 2 最需要注意的是有一个 alloc,因此需要对应的 release。

    选项 1 本质上是“隐藏的”,因为编译器会自动为您生成 setter 和 getter。您没有看到的是,当使用点表示法时,您正在通过 setter,它隐含地包含一个保留调用。因此,您正在分配对象并保留,使其保留计数为 2。

    因此,为了确保它能够在未来被正确释放,您必须将其指定为添加到自动释放池中,以便系统稍后进行清理。这将使保留计数变为 1,然后在您的 dealloc 方法中您可以安全地释放该属性。

    【讨论】:

      猜你喜欢
      • 2012-08-04
      • 1970-01-01
      • 2014-08-26
      • 1970-01-01
      • 2016-05-16
      • 1970-01-01
      • 2017-02-10
      • 2012-09-08
      • 2017-09-06
      相关资源
      最近更新 更多