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& ...
随机推荐
- centos7.2环境yum方式快速搭建lnmp环境nginx+mariadb+php-fpm
centos7.2环境yum方式安装nginx+mariadb+php-fpm 1.安装lnmp环境 安装epel源 yum install -y epel-release 安装 MySQL + PH ...
- 解决JavaFTP上传文件假死问题
之前使用ftp上传文件,代码很稳定,用了快三年,因为数据迁移,从搭建了ftp服务器,配置好ip和账号密码后,再使用之前代码发现: 在下载过程中,程序出现假死的现象,就是,既不报错,也不抛异常,还不终止 ...
- java 完全解耦
只要有一个方法操作的是类而非接口,那么你就只能使用这个类及其子类,如果你想要将这个方法应用于不在此继承结构中的某个类,那么你就会触霉头,接口可以在很大程度上放宽这种限制,因此,我们可以编写可服用性更好 ...
- SendMessage原理初探
今天跟踪一下SendMessage的实现. 用向导先创建一个Windows application. 向导生成了一个简单的窗口,如下. 在File菜单添加SendMessage,顺便添加一个PostM ...
- NOIP2018 货币系统
题面 思路 先分析一下,a集合的子集肯定不存在可以用它来表示的数,a集合是不能够表示的. 所以问题简化了成为选出a的一个子集(个数最少),能够表达a集合所有能表达的数. 接下来继续分析 如:1 2 4 ...
- ***文件上传控件bootstrap-fileinput的使用和参数配置说明
特别注意: 引入所需文件后页面刷新查看样式奇怪,浏览器提示错误等,可能是因为js.css文件的引用顺序问题,zh.js需要在fileinput.js后面引入.bootstrap最好在filein ...
- Javascript之继承(原型链方式)
1.原型链 原型链是JavaScript中继承的主要方法. 每个构造函数都拥有一个原型对象,原型对象都包含一个指向构造函数的指针(constructor),实例都包含一个指向原型对象的内部指针(__p ...
- 【LOJ】#2510. 「AHOI / HNOI2018」道路
题解 读题是做题关键 我们设\(dp[u][l][r]\)表示\(u\)节点上方没改\(l\)条公路和\(r\)条铁路 然后记忆化搜索,枚举这条点改左边还是右边 代码 #include <bit ...
- sublime text3快速生成html头部信息(转)
sublime text3快速生成html头部信息 https://blog.csdn.net/sunshinegirl_7/article/details/49802579 经常见别人创建新的ht ...
- Spring Cache缓存技术的介绍
缓存用于提升系统的性能,特别适用于一些对资源需求比较高的操作.本文介绍如何基于spring boot cache技术,使用caffeine作为具体的缓存实现,对操作的结果进行缓存. demo场景 本d ...