viewDidUnload方法

当系统内存吃紧的时候会调用该方法(注:viewController没有被dealloc)

内存吃紧时,在iPhone OS 3.0之前didReceiveMemoryWarning是释放无用内存的唯一方式,但是OS 3.0及以后viewDidUnload方法是更好的方式

在该方法中将所有IBOutlet(无论是property还是实例变量)置为nil(系统release view时已经将其release掉了)

在该方法中释放其他与view有关的对象、其他在运行时创建(但非系统必须)的对象、在viewDidLoad中被创建的对象、缓存数据等

release对象后,将对象置为nil(IBOutlet只需要将其置为nil,系统release view时已经将其release掉了)

一般认为viewDidUnload是viewDidLoad的镜像,因为当view被重新请求时,viewDidLoad还会重新被执行

viewDidUnload中被release的对象必须是很容易被重新创建的对象(比如在viewDidLoad或其他方法中创建的对象),不要release用户数据或其他很难被重新创建的对象


关于dealloc的官方说明,看的实在是蒙,这里就不贴了。

----------------------------------------------------------------------------------------------------------------------------------------------------------

viewDidUnload 和 dealloc 的区别,关于这两者的区别的文章很多,但是大都是摘抄和翻译官方文档,有的也只是简单的说两句,并没有详细说出两者具体的区别。

在了解两者之间的区别,首先要知道 view 的生命周期,google 里面有很多文章,可以先去搜一下,这里就不详解了。

顾名思义 viewDidUnload 就是当 view 被卸载以后执行的语句,它与 viewDidLoad 是相互呼应的。大家都知道官方的解释是执行类似

self.myOutlet = nil;

的命令,但是为什么这么干,什么时候调用这个方法呢?

这个方法是当应用程序接收到手机内存警告的时候自动调用的方法,目的就是清空内存除当前 viewController 以外,所有已经加载过的 viewController里面的,暂时不再使用的一些控件或数据,以避免应用程序应消耗内存过多被强制关闭。记住,是除当前正在展示的 view 所属 viewController 以外,所有已经在内存里面的 viewController ,执行 viewDidUnload 方法,而不是当前 viewController 执行 viewDidUnload,当然,这些 viewController 不会被 dealloc。所以在 viewDidUnload 里面一般都是释放 IBOutlet 变量和在 viewDidLoad、viewWillAppear、viewDidAppear 等方法能够重建的数据。而由其他页面传递过来的数据或者无法经过 viewDidLoad、viewWillAppear、viewDidAppear 等方法重建的数据则不能释放,举例子说如果在 navigationController 由上一个页面传递过来的一张图片,在 viewDidUnload 里被释放的话,则当 view 再次加载的时候就无法恢复了。

那为什么要写成self.myOutlet = nil; ,实际上这个语法是执行了 property 里的setter 方法,

如果变量定义成retain的话,如:@property (nonatomic, retain) NSArray *dataArray; 它的set实现方法如下:

-(void) setDataArray:(NSString *)newArray{

if(newArray !=dataArray){

[dataArray release];

dataArray =[newArray retain];

}

}

它干了两件事:1、旧数据release 掉,2、新数据nil retain,当然对 nil retain 是无意义的,也是没问题的。

如果写成 myOutlet = nil,那就是简单的把 myOutlet 指向 nil,这样内存就泄漏了,因为老数据没有 release。

而如果仅仅写成 [myOutlet release] 也会有问题,因为当 view 被 dealloc 的时候会 再次 release,程序就出错了,

而对 nil release 是没有问题的。

(在Nil上调用方法: 在Objective-C中,nil对象的作用等同于其他语言的NULL指针。不同的地方在于,在nil上调用方法不会导致程序崩溃或抛出异常。)

dealloc 是当前 viewController 被释放的时候,清空所有当前 viewController 里面的实体和数据来释放内存,该方法也是自动调用的。举例说明当 modalView 被 dismissModalViewControllerAnimated 或者 navigationController 回到上一页的时候,这个方法就会被自动调用。因为这个页面已经不再使用了,所以可以把所有实体和数据都释放(release)掉。

其实两者最大的区别就是:viewDidUnload 是内存除当前的viewController,其他所有 viewController 同时执行,而 dealloc 只是当前 viewController 执行。这个是网上的材料没有说明的。

个人拙见,不对之处还请提正!

PS: 很多朋友都说无法调试 viewDidUnload,其实是可以的。方法是在 iOS 模拟器的菜单里选 硬件 -> 模拟内存警告,这个时候就可以看到 viewDidUnload 里面 NSLog 的东西了,可以试试在打开过的 viewController 里都 NSLog 一下看看效果。而 dealloc 里面可以直接 NSLog。


http://www.cocoachina.com/bbs/read.php?tid=83737

----------------------------------------------------------------------------------------------------------------------------------------------------------

问题一谁应该release


What should be released in viewDidUnload is:

1. IBOutlet properties

2. Anything that will be recreated in viewDidLoad


这个说法不一定对

----------------------------------------------------------------------------------------------------------------------------------------------------------



内存使用的N个建议


用[str setStr:nil]来代替[str release]更好,可消灭野指针,和C++是一样的道理。?

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以上是转载的一位哥们的链接:http://blog.csdn.net/pinklpig/article/details/7364762

写的非常好,但是看了还有一个问题:使用了arc之后,为什么viewDidUnload还是需要调用?

因为在内存紧张的时候,编译器并不知道哪些内存是需要释放的,哪些是不需要释放的,所以还是需要自己手动来管理内存。

如果视图销毁的时候,编译器就知道所有的内存都是需要释放的,编译器就自动释放所有内存。所以dealloc方法就不需要了。



dealloc方法

另外启用ARC之后,dealloc 方法在大部分时候都不再需要了,因为你不能调用实例对象的release方法,也不能调用[superdealloc]。假如原先的dealloc方法只是释放这些对象,Xcode 就会把dealloc方法完全移除。你不再需要手动释放任何实例变量。

如果你的dealloc方法处理了其它资源(非内存)的释放,如定时器、CoreFoundation对象,则你仍然需要在dealloc方法中进行手动释放,如CFRelease(),free()等。这时 Xcode会保留dealloc方法,但是移除所有的release和[superdealloc]调用。如下:

-(void)dealloc

{

AudioServicesDisposeSystemSoundID(soundID);

}