2010-06-17 47 views
1

在我的应用程序工作流程中的各个点上,我需要显示一个视图。该视图内存密集,因此我希望它在被用户丢弃时被释放。所以,我写了下面的代码:可可内存管理

- (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可能会产生错误)。

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

+0

如果您在发布myView后正在调用myView,那么*要*会产生错误。 – walkytalky 2010-06-17 17:35:52

回答

4

myView设置为nil是正确的事情在这里做。 不是这样做是什么产生错误,因为它无法检测地指向一个释放对象。您的代码测试nil以查看是否需要创建新视图,因此应该适当地设置该变量。

1

您将会遇到问题,因为您不使用访问器。您需要为视图定义一个属性。然后,每当你参考视图使用自我点符号。如果你这样做,然后简单地设置视图属性为这样的零:

self.myView=nil; 

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

但是,这是管理视图的不好的方法,特别是如果从nib加载它的话。该视图很可能是控制器对象的必需属性。将其设置为零会导致崩溃。

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

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