我什么时候应该在 - (void)viewDidUnload而不是-dealloc中释放对象?

Tha*_*nks 103 iphone cocoa-touch memory-management objective-c ios

有什么-(void)viewDidUnload好处?

难道我不只是RELASE一切-dealloc?如果视图卸载了,-dealloc反正不会被调用?

Sea*_*phy 51

除了已经指出的内容之外,我还想详细说明背后的逻辑-viewDidUnload.

实现它的最重要原因之一是UIViewController子类通常还包含对视图层次结构中各种子视图的拥有引用.例如IBOutlets,当从笔尖加载或以编程方式在内部加载时,可以设置这些属性-loadView.

子视图的额外所有权通过以下UIViewController方式获得:即使从视图层次结构中删除其视图并释放以保存内存(视图也通过其释放子视图),它们实际上也不会被释放,因为它UIViewController本身仍包含其自身的优秀同时保留对这些对象的引用.释放UIViewController这些对象的额外所有权可确保它们将被释放以释放内存.

您在此处发布的对象通常会在UIViewController视图中重新创建并再次设置re-loaded,无论是来自Nib还是通过实现-loadView.

另请注意,该UIViewController view属性是nil在调用此方法时.


Ste*_*ton 21

正如文件所说:

在低内存条件下调用它时,视图控制器需要释放其视图以及与该视图关联的任何对象以释放内存.

在相同的情况下dealloc不会叫.此方法仅适用于OS3及更高版本.处理iPhone OS 2.x中的相同情况真的很痛苦!

2015年7月更新:应该注意的是viewDidUnload,在iOS 6 中已弃用,因为"在低内存条件下不再清除视图,因此永远不会调用此方法." 所以,现代建议不要担心和使用dealloc.

  • 同样来自文档:"您应该只对以后可以轻松重新创建的对象执行此操作,无论是在viewDidLoad方法中还是在应用程序的其他部分中.您不应使用此方法来释放用户数据或任何其他不可能的信息.容易重建".这也是我自己的问题,谢谢! (6认同)

小智 9

这是因为您通常会设置为@propertyas "(nonatomic, retain)",因此为您创建的setter释放当前对象,然后保留参数,即

self.property = nil;
Run Code Online (Sandbox Code Playgroud)

...做了一些事情:

[property release];
property = [nil retain];
Run Code Online (Sandbox Code Playgroud)

因此,您只用一石二鸟:内存管理(释放现有对象)并将指针指定为nil(因为将任何消息发送到nil指针将返回nil).

希望有所帮助.


Dav*_*des 8

请记住,这viewDidUnload是视图控制器中的方法,而不是视图中的方法.该视图的 dealloc方法将被调用时视图卸载,但视图控制器的 dealloc方法可能不被调用,直到后来.

如果你得到一个低内存警告并且你的视图没有显示,例如你将使用UIImagePickerController让用户拍照的任何时候,你的视图将被卸载并且需要在之后重新加载.


Tha*_*nks 6

结论:

视图控制器具有视图属性.通常,nib或一段代码会向此视图添加其他视图.这通常发生在-viewDidLoad方法中,如下所示:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createManyViewsAndAddThemToSelfDotView];
}
Run Code Online (Sandbox Code Playgroud)

此外,nib文件可以创建一个按钮并将其附加到视图控制器的视图中.

在iPhone OS 2.2上,当从系统调用-didReceiveMemoryWarning时,您必须释放一些东西以释放内存.如果有意义,您可以释放整个视图控制器的视图.或者只是耗费大量内存的内容.

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}
Run Code Online (Sandbox Code Playgroud)

现在,在新的OS 3.0中,有一个-viewDidUnload方法,当由于内存不足而卸载视图时将从系统调用(请纠正我:这究竟是什么时候被调用?)

-viewDidUnload用于释放视图控制器本身和视图所拥有的所有对象.原因是:如果视图控制器保存对视图子节点的引用,即按钮,则引用的子视图将不会被释放,因为它们的保留计数> = 1.在-vi​​ewDidUnload中释放它们之后,它们可以被释放从记忆里.


Gui*_*tro 6

Apple弃用了viewWillUnload,现在你应该使用didReceiveMemoryWarning或dealloc来发布你的objetcs.

在iOS 6中,现在不推荐使用UIViewController的viewWillUnload和viewDidUnload方法.如果您使用这些方法来释放数据,请改用didReceiveMemoryWarning方法.如果未使用此方法,也可以使用此方法释放对视图控制器视图的引用.在执行此操作之前,您需要测试视图不在窗口中.


小智 5

如果视图控制器从导航控制器堆栈中弹出并且未在其他任何位置保留,则将取消分配,并且将调用dealloc而不是viewDidUnload.您应该在dealloc中释放在loadView中创建的视图,但没有必要将变量设置为nil,因为在调用dealloc后不久,变量将不再存在.