ios 我什么时候应该在 -(void)viewDidUnload 而不是在 -dealloc 中释放对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1158788/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When should I release objects in -(void)viewDidUnload rather than in -dealloc?
提问by Thanks
What is the -(void)viewDidUnload
is good for?
有什么-(void)viewDidUnload
好处?
Could I not just relase everything in -dealloc
? If the view did unload, wouldn't -dealloc
be called anyway?
我不能把所有东西都放进去-dealloc
吗?如果视图确实卸载了,-dealloc
无论如何都不会被调用?
采纳答案by Sean Patrick Murphy
In addition to what has already been indicated, I wanted to elaborate more about logic behind -viewDidUnload
.
除了已经指出的内容之外,我还想详细说明-viewDidUnload
.
One of the most important reasons for implementing it is that UIViewController
subclasses commonly also contain owning references to various subviews in the view hierarchy. These properties could have been set through IBOutlets
when loading from a nib, or programmatically inside -loadView
, for instance.
实现它的最重要原因之一是UIViewController
子类通常还包含对视图层次结构中各种子视图的拥有引用。例如,这些属性可以IBOutlets
在从笔尖加载时或以编程方式在 内-loadView
设置。
The additional ownership of subviews by the UIViewController
means that even when its view is removed from the view hierarchy and released to save memory, through which the subviews are also released by the view, they will not actually be deallocated because the UIViewController
itself still contains its own outstanding retaining references to those objects as well. Releasing the UIViewController
additional ownership of these objects ensures they will be deallocated as well to free memory.
子视图的额外所有权UIViewController
意味着即使它的视图从视图层次结构中移除并释放以节省内存,通过这种方式子视图也被视图释放,它们实际上不会被释放,因为它UIViewController
本身仍然包含自己的未完成也保留对这些对象的引用。释放UIViewController
这些对象的额外所有权确保它们也将被释放以释放内存。
The objects that you release here are usually recreated and set again when the UIViewController
view is re-loaded
, either from a Nib or through an implementation of -loadView
.
您在此处释放的对象通常会在UIViewController
视图出现时重新创建和设置re-loaded
,无论是从 Nib 还是通过 的实现-loadView
。
Also note that the UIViewController
view
property is nil
by the time this method is called.
另请注意,该UIViewController
view
属性是nil
在调用此方法时。
回答by Stephen Darlington
As the documentation says:
正如文档所说:
It is called during low-memory conditions when the view controller needs to release its view and any objects associated with that view to free up memory.
当视图控制器需要释放其视图以及与该视图关联的任何对象以释放内存时,它会在内存不足的情况下被调用。
In the same situation dealloc
is notcalled. This method is only available in OS3 and above. Dealing with the same situation in iPhone OS 2.x was a real pain!
在相同的情况下dealloc
是不会叫。此方法仅适用于 OS3 及更高版本。在 iPhone OS 2.x 中处理同样的情况真的很痛苦!
Update July 2015: It should be noted that viewDidUnload
was deprecated in iOS 6 because "Views are no longer purged under low-memory conditions and so this method is never called." So, the modern advice is not to worry about it and use dealloc
.
2015 年 7 月更新:应该注意,viewDidUnload
在 iOS 6中已弃用,因为“在低内存条件下不再清除视图,因此永远不会调用此方法。” 所以,现代的建议是不要担心它并使用dealloc
.
回答by gazzaaa87
This is because you will typically set the @property
as "(nonatomic, retain)"
and as such the setter that is created for you releases the current object and then retains the argument i.e.
这是因为您通常将@property
原样"(nonatomic, retain)"
设置为您创建的设置器释放当前对象,然后保留参数即
self.property = nil;
...does something along the lines of:
...做了一些事情:
[property release];
property = [nil retain];
Therefore you are killing two birds with one stone: memory management (releasing the existing object) and assigning the pointer to nil (since sending any message to a nil pointer will return nil).
因此,您将一石激起二只鸟:内存管理(释放现有对象)并将指针分配给 nil(因为向 nil 指针发送任何消息都将返回 nil)。
Hope that helps.
希望有帮助。
回答by David Maymudes
Remember that viewDidUnload
is a method in the view controller, not in the view. The view'sdealloc
method will get called when the view unloads, but the view controller'sdealloc
method may not be called until later.
请记住,这viewDidUnload
是视图控制器中的方法,而不是视图中的方法。该视图的dealloc
方法将被调用视图卸载的时候,但是视图控制器的dealloc
方法可能不被调用,直到后来。
If you get a low memory warning and your view isn't showing, which will happen for instance about any time you use a UIImagePickerController to let the user take a picture, your view will get unloaded and will need to get reloaded after that.
如果您收到内存不足警告并且您的视图没有显示,例如任何时候您使用 UIImagePickerController 让用户拍照时都会发生这种情况,您的视图将被卸载,之后需要重新加载。
回答by Guilherme Torres Castro
Apple deprecated viewWillUnload, now you shoud use didReceiveMemoryWarning or dealloc to release your objetcs.
Apple 已弃用 viewWillUnload,现在您应该使用 didReceiveMemoryWarning 或 dealloc 来释放您的对象。
In iOS 6, the viewWillUnload and viewDidUnload methods of UIViewController are now deprecated. If you were using these methods to release data, use the didReceiveMemoryWarning method instead. You can also use this method to release references to the view controller's view if it is not being used. You would need to test that the view is not in a window before doing this.
在 iOS 6 中,UIViewController 的 viewWillUnload 和 viewDidUnload 方法现已弃用。如果您使用这些方法来释放数据,请改用 didReceiveMemoryWarning 方法。如果未使用视图控制器视图,您也可以使用此方法释放对视图控制器视图的引用。在执行此操作之前,您需要测试视图是否不在窗口中。
回答by Thanks
Conclusion:
结论:
View Controllers have a view property. Typically a nib or piece of code adds other views to this view. This happens often inside a -viewDidLoad method, like this:
视图控制器有一个视图属性。通常,笔尖或一段代码会向此视图添加其他视图。这通常发生在 -viewDidLoad 方法中,如下所示:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
in addition, a nib file may create a button and append it to the view controller's view.
此外,nib 文件可以创建一个按钮并将其附加到视图控制器的视图中。
On iPhone OS 2.2, when -didReceiveMemoryWarning was invoked from the system, you had to release something to free up memory. You could release the whole view controller's view if that made sense. Or just big memory-consuming contents in it.
在 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
}
Now, in the new OS 3.0, there is an -viewDidUnload method, which will be invoked from the system when the view has been unloaded because of low memory (please correct me: when exactly does this get called?)
现在,在新的 OS 3.0 中,有一个 -viewDidUnload 方法,该方法会在由于内存不足而卸载视图时从系统中调用(请纠正我:什么时候会调用它?)
-viewDidUnload is used to release all objects that were owned both by the view controller itself and the view. The reason: If a view controller holds references to childs of the view, i.e. a button, the referenced child views will not get released, because their retain count is >= 1. After they are released in -viewDidUnload, they can get freed up from memory.
-viewDidUnload 用于释放视图控制器本身和视图拥有的所有对象。原因:如果视图控制器持有对视图子视图的引用,即按钮,引用的子视图将不会被释放,因为它们的保留计数 >= 1。在 -viewDidUnload 中释放它们后,它们可以被释放从记忆里。
回答by Colin
If the view controller is popped from the navigation controller stack and is not retained anywhere else, it will be deallocated, and dealloc will be called instead of viewDidUnload. You should release the views created in loadView in dealloc, but it is not necessary to set the variables to nil, because soon after dealloc is called the variables will no longer exist.
如果视图控制器从导航控制器堆栈中弹出并且没有保留在其他任何地方,它将被释放,并且将调用 dealloc 而不是 viewDidUnload。您应该在 dealloc 中释放在 loadView 中创建的视图,但没有必要将变量设置为 nil,因为在调用 dealloc 之后变量将不再存在。
回答by drvdijk
You can release any subviews you hold on to, for example that UIImageView you retained in your loadView method, or better yet the image that was on that UIImageView.
您可以释放您持有的任何子视图,例如您在 loadView 方法中保留的 UIImageView,或者更好的是该 UIImageView 上的图像。