以编程方式创建的子视图和viewDidUnload

时间:2011-06-22 15:58:33

标签: iphone objective-c ios memory-management

对于视图控制器,必须释放在Interface Builder中设置的任何插座 并在 viewDidUnload 中设置为nil,并且还必须在 dealloc 中发布。

(见:When should I release objects in viewDidUnload rather than in dealloc?

  

实现[ viewDidUnload ]的最重要原因之一是UIViewController子类通常还包含对视图层次结构中各种子视图的拥有引用。这些属性可以在从笔尖加载时通过IBOutlet设置,或者以编程方式在 loadView [加重] 中加载。

我的问题是,我们是否真的需要为视图层次结构中的子视图实现 viewDidUnload ,这些子视图是以编程方式在 loadView (没有Interface Builder)中创建的?

3 个答案:

答案 0 :(得分:5)

这取决于您创建它们的方式以及是否需要在其他地方引用它们。

例如:

- (void)loadView
{
    [super loadView];

    UIButton *someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    someButton.frame = CGRectMake(0, 0, 50, 50);
    [self.view addSubview: someButton];
}

在上面的例子中,您不需要实现viewDidUnload,因为someButton是在loadView中自动释放的。

另一个例子:

- (void)loadView
{
    [super loadView];

    self.someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    someButton.frame = CGRectMake(0, 0, 50, 50);
    [self.view addSubview: someButton];
}

在这个例子中,你会想要使用viewDidUnload,因为你有另一个对someButton的引用。您希望viewDidUnload释放该按钮并重置引用,这样您就不会不正确地使用它以及释放内存。在这种情况下,您还希望在dealloc方法中释放按钮,以防从未调用viewDidUnload。

答案 1 :(得分:2)

你当然应该。但是,如果您查看Apple样本,您会发现有时它们只使用dealloc。如果您知道您的物体在使用后会在合理的时间内解除分配,我认为这是完全合理的。但是,我遵循此模式,因为在某些特殊情况下可能不会调用viewDidUnload。我实际上并没有将发布方法称为如此长的名称:

-(void)releaseRetainedXibAndViewDidLoadObjects
{
    self.myLabel = nil;
    self.myImage = nil;
}

-(void)viewDidUnload
{
    [super viewDidUnload];
    [self releaseRetainedXibAndViewDidLoadObjects];
}

-(void)dealloc
{
    self.myObject = nil;
    [self releaseRetainedXibAndViewDidLoadObjects];
    [super dealloc];
}

您甚至可以从类子类化的特定于应用程序的视图控制器对象执行此操作,以简化问题。

答案 2 :(得分:0)

dealloc方法中执行此操作。无法保证将viewDidUnload被调用。它通常仅在控制器需要卸载视图时调用,例如,当有记忆警告时。另一方面,始终会调用init / dealloc配对。