在viewDidUnload和dealloc中发布?

时间:2010-03-01 00:58:51

标签: objective-c memory-management uiviewcontroller

我一直假设在释放控制器时始终调用viewDidUnload。这是正确的假设吗?

我一直在探索一些奇怪的事情,并在我的控制器viewDidUnload中设置一个断点,它是dealloc。似乎调用dealloc,但永远不会调用viewDidUnload方法。我甚至在我的self.view = nil添加了dealloc,但它似乎仍然无法调用它。

这是否意味着我在viewDidUnload方法中发布的保留视图对象也需要在我的dealloc方法中发布,以确保它们真的消失了?

我知道StackOverflow上还有很多关于viewDidUnload的问题,但是没有一个专门针对这两个方法之间重复发布语句的问题。


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

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

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

我认为它会高2倍。视图保留一次,控制器保留一次。但是在dealloc之后我会期望视图不再释放我的标签,并且控制器不再调用viewDidUnload并释放它。虽然此时可能会有autorelease丢掉计数。

但至少很明显viewDidUnload根本没有被调用,这与此答案相反:Are viewDidUnload and dealloc always called when tearing down a UIViewController?

也许我应该简单地在控制器上的所有dealloc方法中调用[self viewDidUnload]?比可能发生的更糟糕的是,我将属性设置为nil两次,对吧?

1 个答案:

答案 0 :(得分:20)

除非您需要中断保留周期,否则 通常只会在dealloc方法中释放对象。 viewDidUnload是一个例外;它在低内存情况下调用,应该用于释放任何你可以使用的东西。

如果您确实需要在其他地方释放它们,那么请始终在release之后将引用设置为nil。这样可以保护您的应用免受以后爆炸(可能在dealloc)。

请注意,文档非常明确地指出,在调用viewDidUnload时,view属性已经是nil。

相关问题