iOS内存管理 -讲的不错,角度独特
ios的内存管理,包括对象的所有权与引用计数、自动释放、访问器方法与属性、一些会改变引用计数的特殊情况
----- 对象所有权(ownership) 与引用计数 (retain count 、reference count)
当一个所有者(owner,其本身可以是任何一个Objective-C对象)做了以下某个动作时,它拥有对一个对象的所有权(ownership)
1、创建一个对象,包括使用任何名称中包含 "alloc" "new" "copy"的方法
2、保留(retain)一个对象
一个对象可以有多个所有者,一个所有者也可以拥有多个对象
相应的,引用计数增减的基本规则是:
1、当所有者创建一个对象时,该对象的引用计数为1
2、当所有者保留它时,该对象的引用计数加1
3、当所有者释放(release)它时,该对象的引用计数减1
当一个所有者对于一个对象的引用计数的增减总计为0时,它放弃了对这个对象的所有权
从两个不同的角度来看内存问题。
1、当一个对象有着至少一个所有者(owner)的时候,它依然存在;当它没有任何所有者的时候,它会被释放掉
2、从引用计数的角度看,一个对象存在时,其引用计数大于0,当一个对象的引用计数为0时,它会调用dealloc方法并释放掉
两者的关系是:在所有权的背后起作用的机制是引用计数机制。我们只应当使用所有权的概念来管理内存,因为如果试图直接获取对象的引用计数,那么得到的数字会匪夷所思 -- 系统的一些框架会“偷偷”增减对象的引用计数
内存管理的目标:
当一个对象的某个所有者依然需要使用它时,保证这个对象的存在;当一个对象的所有者不再需要它时,保证这个对象被销毁。因此只要任何一个所有者在使用完一个对象之后释放掉它,那么内存管理的目标就可以实现。
任何一个所有者(所有者本身也只是一个对象)所应当遵守的基本步骤:拥有一个对象 -> 使用一个对象 -> 放弃对象的所有权
从引用计数的角度来看:还需要这个对象时,保持对其增减为正;不再需要这个对象时,保持对其增减为0
下图,所有者1和所有者2单独地执行了拥有对象、使用对象、放弃对象所有权的步骤;当所有者1不再需要该对象时及时放弃了所有权,但此时所有者2依然拥有该对象,因此该对象依然存在,所有者2可以继续使用它;当2也不再需要该对象时,也放弃掉所有权;这时对象不再有任何所有者,因此立刻被销毁掉
所有者2只是复制了该对象的指针,并没有使用copy方法,因此复制指针这个操作本身并不增加对象的引用计数;因为所有者2希望能使用该对象,因此通过retain方法成为它的所有者,也保证了所有者1放弃该对象时,对象不被销毁。
右手边前两个步骤的代码实现应该为 if(obj1 != obj){ [obj1 release]; obj1 = [obj retain]; }
有时候一个所有者创建一个对象后,会立刻将该对象的指针传递给其他所有者,这时,这个创建者不希望再拥有这个对象,如果立刻给它一个release,会导致这个对象被立刻被释放掉,这样其他所有者还没来得及保留该对象,解决这个问题的方法是,给对象发送一个autorelease消息:这样创建者不再拥有该对象的所有权:该对象成为自动释放的对象,但不会立刻被释放掉,其他所有者可以有时间保留或者赋值该对象,并成为其唯一所有者。
看一个自动释放的demo,一所有者先用alloc方法创建一个对象,此时该所有者拥有了这个对象,对象的引用计数为1.接着,所有者自动释放该对象,所有者此时已经放弃了所有权,但对象的引用计数在一段时间内依然为1. 此时可以看出自动释放的另一个好处,不会因为忘记给对象发送release 而造成内存泄露。
-(Object *)returnAutoreleaeObject{
object *obj = [object alloc]init];
return [obj autorelease];
}
与自动释放相关的,有一大类构造方法,由它们构造的对象直接就是自动释放的对象,这一类哦鼓噪方法叫便捷方法,比如stringWithFormat , NSArray 的arrayWithObjects:和 arrayWithArray:,UIImage的imageNamed:,NSNumber的numberWithBool等,autoreleae方法会在一段时间以后释放掉一个对象,在这段时间内我们可以安全地使用该对象,这段时间是多久呢?
先看看自动释放池,其是NSAutoreleasePool的实例,包含了收到autorelease消息的对象,当一个自动释放池自身被销毁(dealloc)时,它会给池中每一个对象发送一个realeae消息,一个自动释放的对象,至少能够存活到自动释放池销毁的时候。
自动释放池在每一个时间周期(event cycle)的开始,系统会子弟哦那个创建一个,在每一个事件周期的末尾,系统会自动销毁。可这样理解:当代码在持续运行时,自动释放池是不会被销毁的,此时可以安全的使用自动释放的对象,当代码运行告一段落,开始等待用户输入或者其他事件时,自动释放池就被自动释放掉,池中的对象都会收到一个release消息。
自动释放而非直接释放,可以帮助节省一些代码量,提供开发速度,但有一个直接的缺点:延缓了对象的释放,在有大量自动释放对象的时候,会占用大量内存资源,因此,需要避免大量对象自动释放。
在以下情况,需要手动建立并手动销毁自动释放池:
1、当在主线程外开启其他线程时:系统只会在主线程自动生成并销毁掉自动释放池
2、挡在短时间内制造了大量自动释放对象时:及时地销毁有助于有效利用手机上的内存资源
转:http://qk13warcraft.blog.163.com/blog/static/15754934420129213170934/
iOS内存管理 -讲的不错,角度独特的更多相关文章
- iOS内存管理 ARC与MRC
想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC ...
- iOS内存管理策略和实践
转:http://www.cocoachina.com/applenews/devnews/2013/1126/7418.html 内存管理策略(memory Management Policy) N ...
- iOS内存管理机制解析之MRC手动引用计数机制
前言: iOS的内存管理机制ARC和MRC是程序猿參加面试基本必问的问题,也是考察一个iOS基本功是 否扎实的关键,这样深入理解内存管理机制的重要性就不言而喻了. iOS内存管理机制发展史 iOS 5 ...
- iOS内存管理
iOS内存管理的方式是引用计数机制.分为MRC(人式引用计数)和ARC(自动引用计数). 为什么要学习内存管理? 内存管理方式是引用计数机制,通过控制对象的引用计数来实现操作对象的功能.一个对象的生命 ...
- 【Bugly干货分享】iOS内存管理:从MRC到ARC实践
Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...
- iOS内存管理个人总结
一.变量,本质代表一段可以操作的内存,她使用方式无非就是内存符号化+数据类型 1.保存变量有三个区域: 1>静态存储区 2>stack 3>heap 2.变量又根据声明的位置有两种称 ...
- IOS内存管理学习笔记
内存管理作为iOS中非常重要的部分,每一个iOS开发者都应该深入了解iOS内存管理,最近在学习iOS中整理出了一些知识点,先从MRC开始说起. 1.当一个对象在创建之后它的引用计数器为1,当调用这个对 ...
- iOS内存管理编程指南
iOS 内存管理 目录[-] 一:基本原则 二:成员变量的内存管理 三:容器对象与内存管理 四:稀缺资源的管理 五:AutoRelease 六:其他注意事项 iOS下内存管理的基本思想就是引用计数,通 ...
- iOS内存管理(一)
最近有时间,正好把iOS相关的基础知识好好的梳理了一下,记录一下内存相关方面的知识. 在理解内存管理之前我觉得先对堆区和栈区有一定的了解是非常有必要的. 栈区:就是由编译器自动管理内存分配,释放过程的 ...
- 75.iOS内存管理
堆区和栈区 1.栈区:由编译器自动分配释放,函数的参数值,局部变量等值 2.堆区:一般由开发人员分配释放,若不释放,则可能会引起内存泄漏 NSString *string = @"abcd& ...
随机推荐
- 转:Vue-cli proxyTable 解决开发环境的跨域问题
转:http://www.jianshu.com/p/95b2caf7e0da 和后端联调时总是会面对恼人的跨域问题,最近基于Vue开发项目时也遇到了这个问题,两边各自想了一堆办法,查了一堆资料,加了 ...
- KnockoutJs学习笔记(八)
with binding用于创建一个新的绑定环境(binding context),包含with binding的元素的所有子元素都将处于指定的object的环境限定内. 下面是一个简单的使用with ...
- AxureRP8实战手册
基础操作篇 本篇包含56种常见的基础操作,初学者应在掌握本篇内容后再进行实战案例篇的学习,以免产生学习障碍.同时,建议具备一定基础的读者学习本篇中相对生疏的内容,并加以掌握. 第1章 使用元件 本文目 ...
- hdu 5443 (2015长春网赛G题 求区间最值)
求区间最值,数据范围也很小,因为只会线段树,所以套了线段树模板=.= Sample Input3110011 151 2 3 4 551 21 32 43 43 531 999999 141 11 2 ...
- NET 架构指南频道
NET 架构指南频道 微软在Visual Studio 2017 正式发布的时候也上线了一个参考应用https://github.com/dotnet/eShopOnContainers , 最近微软 ...
- ubuntu下Sprak(IDE)wordcount例子
一.进入IDE界面 cd ~/Downloads/idea/bin idea.sh 二.建立scala项目 Step 1:导入Spark-hadoop对应的包,次选择“File”–> “Proj ...
- 数据库相关--在mac OX10.11.6上安装MySQL
一.之前失败情况 官网下载dmg文件安装.源码安装,下过5.6 5.7 8.0 版本,都可以安装成功,但是在电脑设置界面无法启动,每次点启动输入密码后,均闪一下绿色然后变红色,既然不能界面启动,那 ...
- 多线程十之CopyOnWriteArrayList源码分析
目录 简介 类结构 源码解析 构造方法 add(E e) add(int index, E element) get(int index) remove(int index) 迭代器Iterator遍 ...
- Linux文件的所有权与权限
要了解Linux的权限,需要和Linux的用户与组的概念一并理解,不了解的同学请参考Linux的用户和组 简介 在Linux中,每个文件除了有用户和组的信息以外,还有其对应的权限.可使用来查看. [r ...
- RelativeLayout 高度宽度
RelativeLayout ss = (RelativeLayout) findViewById(R.id.myRelativeLayout); ss.setLayoutParams(new Rel ...