【问题标题】:Dealloc method of UIView subclass not getting calledUIView 子类的 Dealloc 方法没有被调用
【发布时间】:2011-03-25 22:22:17
【问题描述】:

我有一个名为 SettingsViewController 的视图控制器和一个名为 ViewAccounts 的自定义 UIView 子类。在 SettingsViewController 中,我使用下面的代码将 ViewAccounts 视图添加到 SettingsViewController。

 if(!self.viewAccounts)
 {
      ViewAccounts *objViewAccounts= [[ViewAccounts alloc] initWithFrame:CGRectMake(0, yViews, 320, 400) withViewController:self];
      [self.view insertSubview:objViewAccounts atIndex:0];
      self.viewAccounts = objViewAccounts;
      [objViewAccounts release];
}

问题是 ViewAccounts(UIView 的子类)的 dealloc 方法没有被调用。如果我注释这两行代码,就会调用 dealloc 方法。

[self.view insertSubview:objViewAccounts atIndex:0];
self.viewAccounts = objViewAccounts;

我想问题出在保留计数上,当我们使用 insertSubview 或 addSubiew 时它会增加 1,但是如何摆脱它。这是使用它的正确方法吗?

【问题讨论】:

    标签: iphone objective-c xcode ios memory-management


    【解决方案1】:

    请注意:分配 viewAccount 可能会导致僵尸在路上(在原始代码 sn-p 中),因为您在最后一行释放了它。

    我会建议以下方法:

    1. 再次保留 viewAccounts
    2. 不要使用自动释放,因为您没有从该方法返回它
    3. 注意sn -p中方法的dealloc方法

    这就是我在 viewAccounts 保留

    的情况下编写 sn-p 的方式
    if(!self.viewAccounts)
    {
      ViewAccounts *objViewAccounts= [[ViewAccounts alloc] initWithFrame:CGRectMake(0, yViews, 320, 400) withViewController:self];
      [self.view addSubview:objViewAccounts];
      self.viewAccounts = objViewAccounts;
      [objViewAccounts release];
    }
    ...
    - (void) dealloc {
        [super dealloc];
        [viewAccounts release];
        ...
    }
    

    在您的原始代码中发生的情况是保留变量 viewAccounts 在此类生命周期结束时未正确释放,因此未调用 dealloc。

    顺便说一句,当您只 分配 变量时,如果您 重新分配 该变量,尤其是在您 NIL 时,您必须自己管理保留。假设您将变量设置为 NIL,那么可以再次执行 sn-p。但随后您会覆盖该变量并且您无法释放第一个值。如果您使用 retain,Object-C 会为您执行此操作。根据经验,我总是对属性使用 retain,直到您有足够的经验来处理其他情况。

    【讨论】:

    • 非常感谢您提供的重要信息。因为在我使用分配后,应用程序正在退出。现在它工作正常。只是为了确保,如果我们保留一个属性,在 dealloc 方法中,应该使用 self.anyProperty = nil 还是只使用 [anyProperty release] 或两者兼而有之?
    【解决方案2】:

    您可以将 objViewAccounts 设置为自动释放,因为无论如何它都会被 self.view 保留。

    ViewAccounts *objViewAccounts= [[[ViewAccounts alloc] initWithFrame:CGRectMake(0, yViews, 320, 400) withViewController:self] autorelease];
    

    同样关于保留计数,如果属性 self.viewAccounts 被声明为保留,那么保留计数也会增加 1。

    【讨论】:

    • 谢谢。属性 self.viewAccounts 被声明为保留。现在我已将其更改为分配。 autorelease 没有任何区别,正如我猜的那样,它只是将保留计数减少了 1。我认为 release 方法也做同样的事情,除了我们明确地调用它。我不确定,为什么 assign 成功了。无论如何,非常感谢:)
    • 没问题:),那是因为assign不会增加retain count。
    猜你喜欢
    • 1970-01-01
    • 2012-08-19
    • 2013-06-28
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多