可可内存管理

时间:2010-06-17 17:20:02

标签: iphone cocoa cocoa-touch memory-management null

在我的应用程序工作流程中的不同时刻,我需要显示一个视图。该视图非常耗费内存,因此我希望在用户丢弃它时将其解除分配。所以,我写了下面的代码:

- (MyView *)myView {
    if (myView != nil)
        return myView;

    myView = [[UIView alloc] initWithFrame:CGRectZero]; // allocate memory if necessary.
    // further init here

    return myView;
}

- (void)discardView {
    [myView discard];   // the discard methods puts the view offscreen.
    [myView release];   // free memory!
}

- (void)showView {
    view = [self myView];
    // more code that puts the view onscreen.
}

不幸的是,这种方法只能在第一次使用。将视图置于屏幕上的后续请求会导致"message sent to deallocated instance"错误。显然,解除分配的实例与nil不同。我想在[myView release]之后添加一行myView = nil。但是,这可能会导致错误(在该行之后调用myView可能会产生错误)。

那么,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

myView设置为nil是正确的做法。 这样做是产生错误的原因,因为它不可察觉地引用了一个解除分配的对象。您的代码测试nil以查看是否需要创建新视图,因此您应该适当地设置变量。

答案 1 :(得分:1)

因为你没有使用访问器,你会遇到问题。您需要为视图定义属性。然后,每当您引用视图时,请使用自点符号。如果你这样做,那么只需将view属性设置为nil,如下所示:

self.myView=nil;

...将自动触发其释放。

但是,这是管理视图的不好方法,尤其是从nib加载视图时。视图很可能是控制器对象的必需属性。将其设置为nil会引发崩溃。

更好的方法是让视图控制器处理内存问题。在iPhone上,您可以将内存管理代码放在viewDidDisappear:didReceiveMemoryWarning中。在任何情况下,只要控制器处于活动状态,您就不会终止视图,而是释放视图的内存密集部分,例如图片。这使视图成为轻量级shell对象。然后在'viewWillAppear`中重新加载内存密集型部分。

但是,处理此问题的最佳方法是从导航堆栈中实际弹出视图控制器。此时视图控制器会自动清理。