IOS开发的内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956763,共同学习,共同进步!
假如在.h文件里,定义一个变量@property (nonatomic,retain) AController *aController;
疑问1:创建对象时候,一般会使用alloc,new,copy或者mutalbeCopy等方法,
哪种写法是正确的?
A self.aController=[[AController alloc] init];
B self.aController=[[[AController alloc] init] retain];
C self.aController=[[[AController alloc] init] autorelease];
D self->aController=[[AController alloc] init];
答案:C,D 引用计数的主要接口alloc,allocwithzone,new(带初始化) 为对象分配内存,retainCount为“1”,并返回此实例,而调用self.aController,self本身有干了活,他把_aController这个变量相当于又retain一下,因此A的retaincount已经是2了,已经泄露了!因此不需要B这样retain了,加autorelease的话,就不管retaincount是几了,反正都会释放(不过这地方为什么这样我也有点搞不懂,还求达人解释),如果用D话,没有执行aController的setter方法,因为此时retainCount为“1”,所以D也是正确的,C的话也能用,但是不是好的用法
疑问2:在dealloc方法中,这么写有问题吗?

- (void)dealloc{
[self.aController release];
self.aController = nil;
[super dealloc];
}

答案:这里不需要release了,因为self.aController = nil;已经调用了release了,当然也可以这么写

- (void)dealloc{
[self->aController release];
self->aController = nil;
[super dealloc];
}

解释:对于set method来说,用synthesize来让系统帮我们生成的set方法和如下的类似:

- (void)setAbc:(id)newAbc
{
if(_abc != newAbc){
[_abc release];
_abc = [newAbc retain]; //是retain还是copy取决于你property声明时的attributes
}
}

如果新值和成员相等,就不需要进行重复的赋值了,不等的话,需要把新值赋给成员,同时,成员_abc原来的内容就不需要了,这里要先调用release进行释放。(这个具体的原因在那本讲Objective-C的书中写的很清楚,请查看)。
因此在这里,调用self.abc = nil;
就等于已经调用了[_abc release]; 和_abc = nil;
self.abc = nil;和[_abc release]; 都不一定释放对象,因为该对象还可能被别的引用,这里的操作的意图就是:别的地方用没用_abc我不知道,在这里的_abc我不用了。
为什么release后还要设置nil呢?因为是这样的,如果引用 计数等于0还对该对象进行操作,则会出现内存访问失败,crash,所以尽量设置为nil,但是单纯设置为nil,如果retaincount不是0的话,内存一样泄露的,因此应该设置nil的时候,先保证变量的retaincount是0了
疑问3:为什么有些变量不用考虑retain,release呢?
NSString *str1 = @”constant string”;
str1的retain count是个很大的数字。Objective-C对常量字符串做了特殊处理。
当然,如果你这样创建NSString,得到的retain count依然为1
NSString *str2 = [NSString stringWithFormat:@”123”];
但实际上对于 [NSString stringWithFormat:] 这类构造函数返回的对象都是autorelease的,所以也不用考虑retain,release
疑问4:在ARC的情况下,按说不用自己在考虑release了,为什么还会有dealloc方法存在呢?
答案:虽然在ARC下,不用考虑release了,但是我们可能还要释放一些其他的东西,比如delegate,关闭定时器,关闭gps定位等,另外如果在ARC下,我们自己不放心,为了安全,自己释放变量也没有什么错误发生!另外不用再调用[super dealloc]了
比如在ARC下,我们可能会这么写

- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.closeButtonTimer invalidate];
[self.webView setDelegate:nil];
[self setLocationDetectionEnabled:NO];
}

注意:比如Delegate,如果不在dealloc中释放它,如果页面有多线程的调用,比如开辟个线程从网上down图片子类的,它down下来后需要找这个页面,但是可能用户操作比较快,比如点了后退按钮,这时候页面可能已经销毁了,于是就导致页面崩溃了,所以dealloc中要释放掉delegate
疑问5:怎么能知道哪里内存泄露了呢?
这个就不详细解释了,看相关的帖子说的很详细了
http://www.cocoachina.com/newbie/basic/2012/1204/5242.html
疑问6:声明为IBOutlet属性的,在MRC中应该retain还是assign?在ARC中应该是strong还是weak?
在MRC中,应该是retain的,因为IBOutlet本身就是retain的
任何一个被声明为IBOutlet并且在Interface Builder里被连接到一个UI组件的成员变量,会被额外retain一次。
常见的情形如
IBOutlet UILabel *label; |
这个label在Interface Builder里被连接到一个UILabel。此时,这个label的retainCount为2。
所以,只要使用了IBOutlet变量,一定需要在dealloc或者viewDidUnload里release这个变量。
在ARC中,property,我们将其申明为weak(事实上,如果没有特别意外,除了最顶层的IBOutlet意外,自己写的outlet都应该是weak)。通过加载xib得到的用户界面,在其从xib文件加载时,就已经是view hierarchy的一部分了,而view hierarchy中的指向都是strong的。因此outlet所指向的UI对象不应当再被hold一次了。将这些outlet写为weak的最显而易见的好处是你就不用再viewDidUnload方法中再将这些outlet设为nil了(否则就算view被摧毁了,但是由于这些UI对象还在被outlet指针指向而无法释放)。
参考:
http://www.16kan.com/post/214006.html
http://www.ityran.com/archives/1234
疑问7:在ARC在,如果用retain,和用strong有什么区别?
retain关键字在ARC中是依旧可用的,它在ARC中所扮演的角色和strong完全一样。为了避免迷惑,最好在需要的时候将其写为strong,那样更符合ARC的规则。
IOS开发的内存管理的更多相关文章
- IOS开发小记-内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- [转载]对iOS开发中内存管理的一点总结与理解
对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...
- iOS开发ARC内存管理技术要点
本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...
- IOS开发之内存管理--dealloc该写些什么
在非ARC开发环境中,dealloc是类释放前,清理内存的最后机会.到底那些变量和属性该释放呢,一些特殊的类(nstimer,observer)该怎么释放.需要注意的是不释放会引起内存泄露,过度释放也 ...
- (转)iOS开发ARC内存管理技术要点
转自:http://www.cnblogs.com/flyFreeZn/p/4264220.html 本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automati ...
- iOS开发ARC内存管理
本文的主要内容: ARC的本质 ARC的开启与关闭 ARC的修饰符 ARC与Block ARC与Toll-Free Bridging ARC的本质 ARC是编译器(时)特性,而不是运行时特性,更不是垃 ...
- iOS开发--漫谈内存管理(一)
1.MRC与ARC 苹果提供两种内存管理机制:一种是MRC(manual reference count),即手动引用计数:还有一种是ARC(auto reference count).即自己主动引用 ...
- iOS夯实:内存管理
iOS夯实:内存管理 文章转自 内存管理 最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 目录: 基本信息 旧时代的细节 新时代 基本信息 ...
- 高性能JAVA开发之内存管理
这几天在找一个程序的bug,主要是java虚拟机内存溢出的问题,调研了一些java内存管理的资料,现整理如下: 一.JVM中的对象生命周期 对象的生命周期一般分为7个阶段:创建阶段,应用阶段,不可视阶 ...
随机推荐
- ASP.NET vNext (一)- 基本概念和环境配置
ASP.NET vNext (一)- 基本概念和环境配置 转发:微软MVP 卢建晖 的文章,希望对大家有帮助. 编者语:时代在变,在csdn开博一年就发了那么的两篇文章,无论是什么原因都觉得有愧了.但 ...
- GCD && Run Loops学习笔记
1.GCD 使用不同优先级的若干个队列乍听起来非常直接,只是,我们强烈建议,在绝大多数情况下使用默认的优先级队列就能够了.假设运行的任务须要訪问一些共享的资源,那么在不同优先级的队列中调度这些任务非常 ...
- ASP.NET Web Service中使用Session 及 Session丢失解决方法 续
原文:ASP.NET Web Service中使用Session 及 Session丢失解决方法 续 1.关于Session丢失问题的说明汇总,参考这里 2.在Web Servcie中使用Sessio ...
- 【COCOS2DX-游戏开发之三四】cocos2dx 3.0 TableView特殊使用方法:滚动时不能选择等等
cocos2dx 3.0版本号TableView拍生自ScrollView,经常使用来做滚动列表,有几种特殊使用方法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才干选中 ...
- Shell的学习就从重装系统开始吧
小标题:与Fedora的爱恨情仇 干巴巴的shell学习实在枯燥,看来学习姿势还是要从实践入手 起因:传说中的不作死就不会死,昨晚偶遇一本PDF,讲glade编辑界面的,以下就被吸引了,跟着讲解搞出个 ...
- mysql编码的那点事
Mysql编码问题 在php页面可以向mysql插入英文字符,但就是不能插入中文字符,在cmd客户端也可从插入,这是困扰我两天的问题. 在网上找了很多资料,最终确定了是字符编码这个地方出现了问题,首 ...
- hdu 1059 Dividing 多重背包
点击打开链接链接 Dividing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 使用Castle扩展Ibatis.Net,面向接口编程-更优雅的代码
使用Ibatis.Net做项目半年了,甚是喜欢,感觉确实是个简单.轻巧的O/R Mapping框架,特别是将Sql配置在Xml文件中,相当于直接将Dao层抽离了出来. 本文假定读者对Ibatis.Ne ...
- C++关于数字逆序输出的两种思路,及字符串逆序输出
C++关于数字逆序输出的两种思路,及字符串逆序输出 作者:GREATCOFFEE 发布时间:NOVEMBER 15, 2012 分类:编程的艺术 最近在跟女神一起学C++(其实我是不怀好意),然后女神 ...
- C#动态表达式计算(续1)
距上一帖近五天时间,让大家久等了,没想到关注这个话题的也不少人,正如有同志所说的想解决该问题其实是有太多的解决方法,比如动态构造类编译.调用vbscript或者可以采用javascript解析引擎或者 ...