【问题标题】:Why call autorelease for iVar definition in init method?为什么在 init 方法中为 iVar 定义调用 autorelease?
【发布时间】:2010-04-30 09:22:19
【问题描述】:

我刚刚熟悉了 CLLocationManager,发现了几个包含以下 init 方法的示例类定义:

- (id) init {
    self = [super init];

    if (self != nil) {
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
    }
    return self;
}

- (void)dealloc {
    [self.locationManager release];
    [super dealloc];
}

我不明白为什么 iVar 会自动发布。这不是说在init方法结束时就被释放了吗?

看到同样的示例代码在dealloc方法中有iVar释放,我也很疑惑。

有什么想法吗? '

【问题讨论】:

    标签: iphone objective-c xcode core-location cllocationmanager


    【解决方案1】:

    locationManager 是一个可能使用retain 属性设置的属性。

    基本上,如果你只写:

    self.locationManager = [[CLLocationManager alloc] init];
    

    左侧的self.locationManager 设置器保留对分配的CLLocationManager 的引用。但是右侧的CLLocationManager 引用本身从未发布过。此管理器的保留计数永远不会达到零,并且对象永远不会消失 - 这会导致内存泄漏。

    有两种方法可以解决这个问题。 autorelease 分配的对象,正如您在引用的代码 sn-p 中看到的那样 - 或者您将分配的对象分配给临时变量,将临时变量保留到 locationManager 属性,然后显式释放临时变量:

    CLLocationManager *_temporaryReference = [[CLLocationManager alloc] init];
    self.locationManager = _temporaryReference; // this is retained
    [_temporaryReference release];
    

    就内存管理而言,这两种方法是等效的。有些人更喜欢第二种方法,因为他们不喜欢等待自动释放池被“清空”,尤其是在像 iPhone 这样的低内存设备上,这样可以更严格地控​​制对象的生命周期。

    Apple 的 Objective-C Programming Language 文档更详细地解释了此属性。

    【讨论】:

    • 嗨,Alex,你又一次解除了我的困惑。非常感谢
    【解决方案2】:

    还有一个没有临时变量或自动释放的替代方案:

    locationManager = [[CLLocationManager alloc] init];
    

    如果不使用self.locationManager,则不会为该变量调用类的setter 方法,因此不会将保留计数增加到2。编译器会将这些分配更改为[self setLocationManager: locationManager];。这假设您已将变量原型化为保留。

    如果它是一个类变量(它是),你可以进行赋值。这是否是良好的编码实践值得商榷,但在我看来,这取决于它在课堂开始时的位置。

    【讨论】:

      【解决方案3】:

      如果您的 self.locationManager 是一个保留它的属性,那么它会设置保留。通过执行 alloc,您确实将保留计数设置为 +1,这意味着到函数结束时它是 +2。当您说自动释放时,它将是 +1(因为保留属性)。您也可以在将其设置为属性后显式释放它,但是您所做的代码更少且易于阅读。

      【讨论】:

      • 这是误导。自动释放不会更改保留计数。它所做的只是将对象添加到自动释放池中,当池耗尽时,它将向对象发送释放。无论如何,最好不要考虑保留计数。只考虑所有权。该对象是使用 alloc 方法获得的,因此您拥有该对象。因此,您必须释放它或自动释放它以在您完成它时放弃所有权。可以安全地留下该财产来解决它自己的所有权问题。
      • 感谢两位的澄清。我认为这很清楚,并且为 Jeremy 的保留计数课程感到高兴,因为这一切都归结为......
      • 杰里米的评论很重要。 “自动释放池”可能应该被称为“自动释放列表”,因为人们经常看到“池”这个词并错误地认为它类似于堆或实际包含对象的内存区域。自动释放只是一种延迟消息传递工具。
      猜你喜欢
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多