代码之家  ›  专栏  ›  技术社区  ›  Alex Wayne

在viewdidUnload和Dealloc中释放?

  •  14
  • Alex Wayne  · 技术社区  · 14 年前

    我有一段时间一直在假设 viewDidUnload 总是在释放控制器时调用。这是一个正确的假设吗?

    我只是在探索一些奇怪的东西,并在我的控制器中设置了一个断点 可视负载 而且它的 dealloc . 看来 释放内存 被调用,但 可视负载 从未调用方法。我甚至加了一个 self.view = nil 对我 释放内存 但它似乎仍然不叫它。

    这是否意味着我在 可视负载 方法也需要在我的 释放内存 确定他们真的离开的方法?

    我知道还有很多关于stackoverflow的问题 可视负载 但没有一个专门解决这一问题,即两种方法之间的发布语句重复。


    在3.1.2 SDK上的新项目中有一个更具体的示例:

    @implementation TestViewController
    
    @synthesize label;
    
    - (IBAction)push {
        TestViewController *controller = [[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil] autorelease];
        [self.navigationController pushViewController:controller animated:YES];
    }
    
    - (void)viewDidUnload {
        self.label = nil;
        NSLog(@"viewDidUnload was called");
    }
    
    - (void)dealloc {
        [super dealloc];
        NSLog(@"label retain count: %i", [label retainCount]);
    }
    
    @end
    

    我的应用委托创建了一个简单的导航控制器,其中一个作为根控制器。当我点击链接到的按钮时 push 3次,然后按后退按钮3次,生成以下输出。

    ViewDidUnloadTest[2887:207] label retain count: 2
    ViewDidUnloadTest[2887:207] label retain count: 2
    ViewDidUnloadTest[2887:207] label retain count: 2
    

    比我想象的要高2个。一次由视图保留,一次由控制器保留。但之后 释放内存 我本以为视图会消失,释放我的标签,控制器也会消失。 可视负载 然后释放它。尽管可能有 autorelease 在那里,在这一点上取消了计数。

    但至少很明显 可视负载 完全没有接到电话,这与这里的回答相反: Are viewDidUnload and dealloc always called when tearing down a UIViewController?

    也许我应该打个电话 [self viewDidUnload] 在控制器上的所有释放方法中?比可能发生的更糟糕的是我两次将一个属性设置为零,对吗?

    1 回复  |  直到 14 年前
        1
  •  20
  •   bbum    14 年前

    除非你需要打破保留周期,否则你应该 通常地 只在你的 dealloc 方法。 viewDidUnload 是一个异常;它在内存不足的情况下被调用,应该用于释放任何您能释放的东西。

    如果您确实需要在其他任何地方释放它们,那么在 release . 这样可以防止你的应用程序在以后爆炸(可能在 释放内存 )

    注意,文档非常明确地调用了当 可视负载 被称为。