【问题标题】:Cocoa memory management可可内存管理
【发布时间】:2010-06-17 17:20:01
【问题描述】:

在我的应用程序工作流程的各个阶段,我都需要展示一个视图。该视图非常占用内存,因此我希望在用户丢弃它时将其释放。于是,我写了如下代码:

- (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 的任何调用都可能会产生错误)。

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

【问题讨论】:

  • 如果您在发布 myView 后调用它,您希望产生错误。

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


【解决方案1】:

myView 设置为nil 是正确的做法。 这样做会产生错误,因为它不可检测地引用了已释放的对象。您的代码测试 nil 以查看它是否需要创建新视图,因此您应该适当地设置变量。

【讨论】:

    【解决方案2】:

    您会遇到问题,因为您不使用访问器。您需要为视图定义一个属性。然后,每当您参考视图时,请使用自点符号。如果你这样做,那么只需像这样将 view 属性设置为 nil:

    self.myView=nil;
    

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      相关资源
      最近更新 更多