【问题标题】:Non retained objects: when are they released?非保留对象:它们何时释放?
【发布时间】:2012-02-15 00:01:49
【问题描述】:

在初始化方法中,我有以下代码

- (id)init {

    self = [super init];

    if (self) {

        UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        tempButton.frame = CGRectMake(0,0,300,44);

        // some custom code...

        self.myButton = tempButton;
    }

    return self;
}

其中myButton 是保留属性。 我知道,就内存管理规则而言,此方法等于其他方法:

- (id)init {

    self = [super init];

    if (self) {

        UIButton *tempButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,300,44)];

        // some custom code...

        self.myButton = tempButton;
        [tempButton release];
    }

    return self;
}

但在这种情况下,我需要使用第一个“版本”,因为 buttonType 属性是只读的,并且在按钮初始化后我无法更改它。

由于我发现自己在整个应用程序的多个方法中使用“非初始化发布”版本,并且对于几个对象(其中大多数是 NSString),我的问题是:在这种情况下不计算分配给保留对象的属性,何时释放tempButton 对象?也许在方法/if语句的末尾?还是第一个“版本”会导致内存使用量增加,因为对象不是立即释放而是在一定时间后释放?

【问题讨论】:

    标签: ios memory-management retain


    【解决方案1】:

    我认为您在这里有点困惑:在您的两个 sn-ps 中,您创建了一个 tempButton 对象,但随后您将其分配给了 self.myButton。此时,tempButtonself.myButton 都是指向同一个对象的指针。现在,大概您正在使用的myButton @property 是一个强大的属性,因此通过将tempButton 分配给它,您可以增加它的保留计数,因此在任一版本的代码中,它的保留计数都会为+ 1 结尾,并且不会被释放。

    如果假设myButton 不是一个强属性,那么您的代码中就会出现错误,并且在这两种情况下tempButton 都会被提前释放并解除分配。以下是这两种情况下会发生的情况:

    在您的第一个版本中,由于您获得的 tempButton 不是来自 initcopy 方法,因此它的保留计数为 +1,但会自动释放。在运行循环的当前迭代结束时,自动释放将启动,使其保留计数为 0 并导致其被释放。

    在第二个版本中,您首先会获得一个保留计数为 1 的 tempButton,因为它来自 init 方法。但稍后您显式释放它,使其保留计数为 0,此时它立即被释放。

    【讨论】:

    • 哦,好吧,我错过了运行循环部分。您是否可以更准确地了解“运行循环的当前迭代”?该迭代是否与单个方法或更长的时间相关联,也许是固定的时间量?可能是整个应用程序生命周期?我试图通过阅读教程来了解更多,但没有人真正明确地解释这一点。
    • “运行循环的当前迭代”实际上与我所能做到的一样精确。运行循环是 Cocoa 中的事件处理循环。如果您想了解更多,这里有一篇很好的博文:blog.shinetech.com/2009/06/02/run-loops-vs-threads-in-cocoa
    【解决方案2】:

    非init方法完全一样:

    UIButton *tempButton = [[[UIButton alloc] initWithFrame:CGRectMake(0,0,300,44)] autorelease];
    

    所以我们的想法是更多地了解自动释放池的工作原理,它在大多数情况下非常有用,但你需要了解它是如何工作的,以防你稍后在应用程序中使用该对象。 并且要注意一些事情,当您将临时按钮添加到您的视图时,该视图将保留它,并在将其从其中删除时释放它,您可以使用工具并检查对象的保留计数,如果您希望查看如何释放/如果你想看到它的实际效果,retain 会继续进行。

    【讨论】:

      猜你喜欢
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      • 2011-11-18
      • 1970-01-01
      相关资源
      最近更新 更多