【内存管理】:谁应该写在viewDidUnload里,谁应该写在dealloc里,arc之后viewDidUnload怎么用

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 方法,也不能调用[super dealloc]。假如原先的dealloc 方法只是释放这些对象,Xcode 就会把 dealloc 方法完全移除。你不再需要手动释放任何实例变量。

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

- (void) dealloc

{

AudioServicesDisposeSystemSoundID(soundID);

}

时间: 2025-01-02 04:29:20

【内存管理】:谁应该写在viewDidUnload里,谁应该写在dealloc里,arc之后viewDidUnload怎么用的相关文章

IOS内存管理

原文链接:http://blog.csdn.net/weiqubo/article/details/7376189 1.  内总管理原则(引用计数)    IOS的对象都继承于NSObject,   该对象有一个方法:retainCount ,内存引用计数. 引用计数在很多技术都用到: window下的COM组件,多线程的信号量,读写锁,思想都一样.       (一般情况下: 后面会讨论例外情况)    alloc      对象分配后引用计数为1    retain    对象的引用计数+1

OC_内存管理:MRC与ARC

内存管理 1.1内存管理 1.1.1 C的内存管理,以及麻烦之处 char *p = (char *)malloc(100*sizeof (char)); 这是C的动态内存分配,我们手动跟系统申请了100个字节的内存:或者说系统在堆里开辟了100个字节的空间,并将这个空间的首地址返回给指针变量p. free(p); 使用完成后,手动跟系统释放内存空间:或者说系统回收空间. 如上就是C里简单的内存管理. C的内存管理,我们手动申请,手动释放.这样来看,我们只需要注意三个问题就好了: 1,申请内存,

【点杀ios】内存管理

1.为什要进行内存管理 ios中,每个应用程序所能占有的内存是有限制的.如果你的应用程序所占用的内存超过了这个限制,系统会给你发出内存警告.如果警告后你的程序依然继续占用过多内存,那么系统有可能强制关闭你的应用程序(闪退).并且,如果内存管理没做好,对程序的流畅度也会产生很大的影响.所以,我们在开发应用程序的过程中,要进行内存管理. 2.对什么进行管理: 内存分为堆内存和栈内存.栈内存的分配和释放是系统做的,程序员无法参与.而堆内存,是程序员进行管理的.分配和释放是程序员完成的. 任何继承了NS

Objective-C高级编程:iOS多线程及内存管理(第一章翻译)

写在翻译之前:当初看到这本书的时候,感觉深入浅出讲得比较到位,但是在市面上看到的翻译版本翻译的却没有原著的精髓和味道.所以产生了自己将其翻译一下给初学者一些便利的想法.所以才有了这个系列的第一章的翻译.目前剩余的部分依然在翻译过程中,估计不久之后就可以陆续地发出了. 因为本人的水平或者用词问题,本翻译难免有不周详或不正确之处.如果有人看到还望指出,我一定会尽力地修改那些不正确的部分,让更多的人可以看到更优质的资料. Chapter 1 Life before Automatic Referenc

内存管理 & 内存优化技巧 浅析

内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户体验.如何让回收那些不再使用的对象呢?本文着重介绍OC中的内存管理. 所谓内存管理,就是对内存进行管理,涉及的操作有: 1.分配内存:比如创建一个对象,会增加内存占用: 2.清除内存:比如销毁一个对象,会减少内存占用. 内存管理的管理范围: 1.任何继承了NSObject的对象: 2.对其他非对象类

内存管理 浅析 内存管理/内存优化技巧

内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户体验.如何让回收那些不再使用的对象呢?本文着重介绍OC中的内存管理. 所谓内存管理,就是对内存进行管理,涉及的操作有: 1.分配内存:比如创建一个对象,会增加内存占用: 2.清除内存:比如销毁一个对象,会减少内存占用. 内存管理的管理范围: 1.任何继承了NSObject的对象: 2.对其他非对象类

iOS内存管理策略和实践

来源:http://www.baidu.com/link?url=irojqCBbZKsY7b0L2EBPkuEkfJ9MQvUf8kuNWQUXkBLk5b22Jl5rjozKaJS3n78jCnSsUZjVQvFIW1IKcJMlR2fGj9eiy-gCY7ulTRyEuAi 关于iOS内存管理 应用程序内存管理是:程序运行时,开辟的内存空间.使用它,释放它的过程,写的好的程序尽可能少使用内存.在Objective-C中,内存管理被看做是:在很多数据.代码下,分配 转自hherima的博客

OC内存管理(二)

一:autorelease 1> autorelease原理:将我们创建的对象放到一个对象释放池中(是一个栈区)当池子释放时,会将池子中的对象都做一次release操作(自动释放池存放在一个池子中,就近原则,符合先进后出) 2>自动释放池的创建方式 (1)ios 5.0以前的创建方式 NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init]; ````````````````` [pool  release];//[pool drain]

Swift语言的内存管理哦,还等什么?点进来!

//*********Swift语言的内存管理基础************* //内存管理:针对的是实例的内存占用的管理(放在堆里面) //实例:1,由class类型构建的实例 2.闭包对象 /* 内存管理技术:ARC:Automatic Reference Count 自动:由于语言本身帮我们管理内存,不需要我们手机去管理 比如在c中就调用dealloc() 引用:let p = Person() p就是对Person()这个对象的一个引用 计数: let p = Person()   +1

OC内存管理(MRC)

首先说明一下几块存储区域:栈区(局部变量.函数参数值).堆区(对象.手动申请/释放内存).BSS区(未初始化的全局变量.未初始化的静态数据).常量区(字符串常量以及初始化后的全局变量.初始化后的静态数据).代码区(存放函数体的二进制代码) 1.为什么需要内存管理 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当某个APP所占用的内存超过系统规定限定内存大小时,系统就会发出内存警告,系统会向该APP发送Memory Warning消息.收到此消息后,需要该APP回收一些不需要再