iOS学习之内存管理
1.1 引用计数 Reference Count
1.2 自动引用计数,ARC(Automatic Reference Counting)
- 1引用计数
引用计数(Reference Count)是一个简单而有效的管理对象生命周期的方式。当我们创建一个新对象的时候,它的引用计数为 1,当有一个新的指针指向这个对象时,我们将其引用计数加 1,当某个指针不再指向这个对象是,我们将其引用计数减 1,当对象的引用计数变为 0 时,说明这个对象不再被任何指针指向了,这个时候我们就可以将对象销毁,回收内存。
内存管理五种思考方式:
- 自己生成的对象,自己持有(自生自持)
- 非自己生成的对象,自己也能持有(非自生自持)
- 不需要自己持有的对象释放
- 非自己持有的对象无法释放
- 不要向已经释放的对象发送消息
1. 自生自持
用以下方法生成对象自己持有(计数加一):
- alloc、new、copy、mutableCopy
- allocMyobject、newThatObject、copyThis、mutableCopyYourObject
id obj=[NSObject alloc]init];(计数加1)
2. 非自生自持
使用retain使非自生可自持
Id obj=[NSMutableArray array];(计数不加1)
[obj retain];(计数加1)
3. 不需要自己持有的对象释放
使用alloc、new、copy、mutableCopy或者retain方法持有的对象,一旦不需要,使用release方法释放
[obj release];
4. 非自己持有的对象无法释放
Id obj=[obj0 object];
[obj1 release]; (obj1没有自己持有,释放的话会造成程序异常崩溃)
5. 不要向已经释放的对象发送消息
我们向一个已经被回收的对象发了一个 retainCount 消息,所以它的输出结果应该是不确定的,如果该对象所占的内存被复用了,那么就有可能造成程序异常崩溃
自动释放池原理:
调用release会立刻将保留计数减1,还可能回收对象,使用authorelease,计数会在稍后减1,通常是在下一次“事件循环”。在方法返回对象时很有用。
2.ARC
- 由于ARC是自动执行retain,release,autorelease,dealloc是不能调用的。
- ARC必须遵守的方法命名规则:
以alloc,new,copy,mutableCopy,开头的。其返回的对象规调用者所有。(自生自持)。
- ARC 管理对象生命的办法基本上就是:在合适的地方插入“retain”,“release”操作。
- CoreFoundation对象不归ARC管理
ARC 帮我们解决了引用计数的90%问题,但是仍还有 10% 内存管理,是需要自己处理的
需要自己维护这些对象的引用计数。
对于问题主要体现在:
- 过度使用 block 之后,无法解决循环引用问题。
- 遇到底层 Core Foundation 对象,需要自己手工管理它们的引用计数时,显得一筹莫展。
1. 循环引用(Reference Cycle)问题
1) 相互引用了对方作为自己的成员变量
解决方法:
- 主动断开循环引用
明确知道这里会存在循环引用,在合理的位置主动断开环中的一个引用。
主动断开循环引用这种操作依赖于程序员自己手工显式地控制,相当于回到了以前 “谁申请谁释放” 的内存管理年代,所以这种解决方法并不常用
- 使用弱引用
弱引用虽然持有对象,但是并不增加引用计数,这样就避免了循环引用的产生
两个 ViewController A 和 B,ViewController A 需要弹出 ViewController B,让用户输入一些内容,当用户输入完成后,ViewController B 需要将内容返回给 ViewController A。这个时候,View Controller 的 delegate 成员变量通常是一个弱引用,以避免两个 ViewController 相互引用对方造成循环引用问题。
使用Xcode 的Instruments检测循环引用
:Product -> Profile,然后选择 “Leaks”,
2. Core Foundation 对象的内存管理
对于 Core Foundation 对象,由于不在 ARC 管理之下,我们仍然需要延续以前手工管理引用计数的办法
- CFRetain 和 CFRelease 两个方法,读者可以直观地认为,这与 Objective-C 对象的 retain 和 release 方法等价。
所以对于底层 Core Foundation 对象,我们只需要延续以前手工管理引用计数的办法即可。
这就引入了bridge相关的关键字,以下是这些关键字的说明:
- __bridge: 只做类型转换,不修改相关对象的引用计数,原来的 Core Foundation 对象在不用时,需要调用 CFRelease 方法。
- __bridge_retained:类型转换后,将相关对象的引用计数+ 1,原来的 Core Foundation 对象在不用时,需要调用 CFRelease 方法。
- __bridge_transfer:类型转换后,将该对象的引用计数交给 ARC 管理,Core Foundation 对象在不用时,不再需要调用 CFRelease 方法。
iOS学习之内存管理的更多相关文章
- iOS夯实:内存管理
iOS夯实:内存管理 文章转自 内存管理 最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 目录: 基本信息 旧时代的细节 新时代 基本信息 ...
- IOS开发的内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- IOS开发小记-内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)
概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...
- python学习Day9 内存管理
复习 :文件处理 1. 操作文件的三步骤:-- 打开文件:此时该文件在硬盘的空间被操作系统持有 | 文件对象被应用程序持用 -- 操作文件:读写操作 -- 释放文件:释放操作系统对文件在硬盘间的持有 ...
- [转载]对iOS开发中内存管理的一点总结与理解
对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...
- RT-Thread学习2 —— 内存管理学习记录
RT-Thread学习2 -- 内存管理学习记录1 小内存管理算法(mem.c) 1. 小内存管理法: 小内存管理算法是一个简单的内存分配算法.初始时,它是一块大的内存.当需要分配内存块时,将从这个大 ...
- 包建强的培训课程(12):iOS深入学习(内存管理、Block和GCD等)
@import url(/css/cuteeditor.css); @import url(http://i.cnblogs.com/Load.ashx?type=style&file=Syn ...
随机推荐
- 关于</div>的粗浅理解
</div>作为c#中常用的一个标签,在写多个区域的内容时有着十分重要的作用.如果写简单的网页时不用div可能感受不到太大的影响,但是在写较为复杂的程序时div的分隔作用就很明显了,改动大 ...
- [课程设计]Scrum 2.0 多鱼点餐系统开发进度(第二阶段项目构思与任务规划)
[课程设计]Scrum 2.0 多鱼点餐系统开发进度 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅到店点餐系统WEB ...
- netbeans中给jpanl添加背景图片制定代码的理解——匿名内部类继承父类
此测试是为了仿照在netbeans中给jpanl添加背景图片的制定代码的执行过程 在JpDemo中定义了个Car类的数据类型,但在给其赋值对象时使用了匿名内部类,继承了Car类,是其子类,并重写了父类 ...
- [问题2014S01] 解答
[问题2014S01] 解答 因为 \(f(x_1,\cdots,x_n)\) 为 \(2\) 次 \(n\) 元对称多项式, 故 \[f(x_1,\cdots,x_n)=a\sum_{i=1}^n ...
- excel如何用公式判断单元格的值是否为数字、英文、中文,以及相应的计数
一.excel如何用公式判断单元格的值是否为数字.英文.中文. A列为数据列,B列为判断列=LOOKUP(CODE(ASC(A1)),{48,65,123;"数字","英 ...
- 判断ie?
<!DOCTYPE html> <html lang="en"> <head> <script type="text/javas ...
- Intellij自动下载导入框架包
忽然发现intellij尽然可以自动导入 框架所需的包,而且可以选择jar包版本,瞬间发现Maven,gradle管理jar包还得写配置文件弱爆了. 以Hibernate为例: 1.ProjectSt ...
- kd tree学习笔记 (最近邻域查询)
https://zhuanlan.zhihu.com/p/22557068 http://blog.csdn.net/zhjchengfeng5/article/details/7855241 KD树 ...
- openfire源码修改聊天消息发送内容
/** * $RCSfile: MessageRouter.java,v $ * $Revision: 3007 $ * $Date: 2005-10-31 13:29:25 -0300 (Mon, ...
- 简单回忆一下JavaScript中的数据类型
说到JavaScript,大家都应该知道,它是一门脚本语言,也是一门弱类型语言,也是一门解析型的语言,同时也是一门动态类型的语言. 很好,至于JavaScript中数据类型.其分为基本数据类型和复杂数 ...