Objective C
2015 年 4 月 22 日
Objective C: 内存管理(1)
无论硬件条件如何发展,性能都是我们程序员每一天都要解决的问题,很多初级 Ruby 程序员会说,去他妈的性能,性能能当饭吃吗,我们要的生产效率。但是你知道吗,为了使 Ruby 以及 Rails 成为最具生产效率的语言和 Web 框架,Matz 和 DHH 解决多少底层的性能问题吗。而内存管理则属于性能问题中更为基础的部分,这就是为什么面试的时候为什么热衷于考察候选人对于各种语言的内存管理熟悉程度, 以及算法设计能力,因为这两种能力是区别程序员水平的最佳标准。本文将介绍在 Objective C 中, 内存管理是如何进行的.
自动引用计数
我们在写 C/C++ 语言程序的时候,malloc 和 free, new 和 delete 是对好兄弟,这样可以才能保证内存的正常释放,同样在 Objective C 中,不再使用的内容也是需要我们自己去释放的,对象是否被释放取决于对象的引用计数是否为0. Objective C 中内存管理基于自动引用计数,而自动引用计数的工作思想是:
- 自己生成的对象自己持有
- 非自己生成的对象自己也能持有
- 不再需要自己持有的对象时释放
- 非自己持有的对象不能释放
每一次对象被释放,对象的引用计数自动 -1, 当对象的引用计数为 0, 对象即被废弃. 对应的 Objective C 中的方法如下:
# | 对象操作 | Objective C 方法 |
---|---|---|
1 | 生成并持有对象 | alloc/new/copy/mutableCopy |
2 | 持有对象 | retain |
3 | 释放对象 | release |
4 | 废弃对象 | dealloc |
所以引用计数对于 Objective C 中的内存管理就极为重要,那么引用计数是如何被管理的呢,对有些语言引用计数是通过内存块头部来管理的。那么做的好处是用少量的代码量级可以完成,而且能够统一管理引用计数和对象内存块。但是在 Objective C 中,引用计数是通过引用计数表来管理的,这样对象内存块的分配就无需分配内存块头部,而且引用计数表纪录中存有内存块地址,可以从记录中追溯到个对象的内存块,这样即使出现了故障导致对象占用的内存块损坏,但只要引用计数表没有被损坏,就能确认各内存块的位置。同时利用工具检测内存泄漏的时候,引用计数表的各记录也有助于检测个对象的持有者是否存在。
autorealase
我们都知道,在 C/C++ 中,局部变量在超出其作用域的时候会被自动废弃。Objective C 中的autorelease 的工作方式和他们类似,它的具体使用方法是:
- 生成并持用 NSAutoreleasePool 对象
- 对用已经分配对象的 autorelease 实例方法
- 废气 NSAutoreleasePool 对象
简单的代码示例如下:
NSAutoreleasePool *pool = [[NSAutorelease alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
[pool drain];
其内部的原理主要当分配的对象调用 autorelease 方法时,pool 将调用自己的 addObject 方法,将对象添加到 pool 的持用对象 array 中,当pool 调用 drain 的时候实际上相当于 obj release,也就是释放对象。
最后
通过上述简介, 相信你对 Objective C 的内存有了一些基础的了解.