【问题标题】:how much to release in viewDidUnload在 viewDidUnload 中释放多少
【发布时间】:2011-08-25 20:36:09
【问题描述】:

Apple 模板在 viewDidUnload 中提供了此注释:

// Release any retained subviews of the main view. // e.g. self.myOutlet = nil;

所以我通常在 viewDidUnload 中将 IB Outlets 设置为 nil,然后在 dealloc 中释放它们。问题是,我所有其他保留的 ivar 对象,其中一些是通过程序添加的视图,而另一些是数据模型,它们是否也应该在这两种方法中处理?如果没有,为什么不呢?

从这个答案here 我收集到只有与视图相关的对象应该作为=nil 语句进入viewDidUnload,这可能应该包括非IB Outlet 保留视图,对吗?然后,所有其他对象,包括数据模型,都应该作为release 语句进入dealloc。这是正常的做法吗?

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    viewDidUnload 由于内存不足而被调用,以卸载当前不可见的视图控制器的视图。此时视图控制器的视图对象已被释放,这意味着作为 viewController.view 子视图的所有对象都已被释放,但如果您将它们保留在 ivars 中,它们不会被释放。

    您应该释放在再次加载视图时将重新创建的任何对象,或者您可以根据需要轻松重新创建的对象。下次使用视图时,将从 NIB 或调用 loadView 重新创建视图,以便重新创建您发布的所有内容。

    当您的视图来自 NIB 时,NIB 中指定的所有视图对象都会创建并添加为视图控制器视图的子视图。任何带有 IBOutlets 的 ivars 也连接到这些子视图,因此您也“拥有”这些对象(您对它们有保留)。您需要释放这些 ivars,以便它们实际上会被释放。

    当您在 loadView 中以编程方式创建视图时,您还应该释放您的 ivars 保留的那些对象,这些对象将在下次加载视图时在 loadView 中重新创建。

    对于您在 viewDidLoad(或 viewWillAppear 或其他地方)中创建的任何内容,例如数据模型,如果您可以在稍后再次加载视图或需要对象时“轻松”重新创建它,那么它应该在 viewDidLoad 中释放到减少内存使用。实际上对于非视图项,比如数据模型,我会在 didReceiveMemoryWarning 中发布它。

    使用 setter 将 nil 分配给保留属性会导致向它们发送释放,当您编写 self.myOutlet = nil 时,您正在调用 setter 方法,该方法的实现如下:

    -(void)setMyOutlet:(id)newObject
    {
        [newObject retain];     // does nothing if newObject is nil
        [myOutlet release];    
        myOutlet = newObject;
    }
    

    【讨论】:

    • 如果您将保留的数据模型作为视图控制器的 ivar,并且希望在卸载视图控制器的视图时将这些数据保留在内存中,听起来 viewDidLoad 不是一个好方法创建这个模型的地方。在这种情况下,您会推荐一种委托方法来创建视图控制器的 ivars 吗?或者,也许更传统的做法是,通过 Core Data 将数据保存在设备上。我的问题是数据模型从网络获取其内容;发布它需要再次下载才能在以后继续使用它。
    • 如果您从网络下载数据,我通常不会称其为“容易”重新创建的东西。我不会发布它,否则会将其存储在核心数据、plist、NSUserDefault 或 SQL DB 中,具体取决于它的大小和结构。
    猜你喜欢
    • 2011-01-22
    • 2011-11-18
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2011-04-05
    • 2011-03-14
    • 1970-01-01
    • 2011-11-09
    相关资源
    最近更新 更多