读书笔记系列—Objective-C中的内存管理

Posted 月球上漫谈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读书笔记系列—Objective-C中的内存管理相关的知识,希望对你有一定的参考价值。

我们都知道,为了方便编译器进行内存管理,苹果在Objective-C和后来推出的Swift中都采用了自动引用计数机制(ARC)。那么什么是内存管理,引用计数又是什么?本文尝试从Objective-C的引用计数实现出发,结合一些资料,思考当初开发者是怎么设计并实现这一机制。

ARC,自动引用计数(Automatic Reference Counting)的缩写,是指在内存管理中对引用采取自动计数的技术。值得一提的是,为了方便管理内存,C++ 11也引进了智能指针的概念,而智能指针的原理正是自动引用计数。

什么是内存布局

在了解什么是引用计数之前,我们先来回顾一下一些基础知识。

程序的源代码在经过下面的四个阶段后

预处理编译汇编链接

可以得到可被计算机/智能设备识别并运行的可执行文件。

而计算机或智能设备运行程序的过程,实际上也可以简单地分为以下几步

ios系统中,程序启动后,栈区,全局区和代码区的大小都是固定的了。栈区大小一般为几M,主要用来存储函数参数和非动态申请的大部分局部变量等;代码区存储程序源码,类对象和字面值;全局区存储全局变量/常量,静态变量/常量和类变量等。但是堆区的大小是不固定的,由系统分配,程序共享,一般用来存储我们动态申请内存创建的对象等;

为什么要学习内存管理呢,一方面是因为计算机或智能设备的内存都是有限的,每个程序一般都会申请大量对象,如果能避免内存泄漏或者在对象不再被使用的情况下及时释放对象内存,可以优化程序的内存占用。为什么很多苹果应用都能做到如丝般顺滑,在本文后面提到的用于及时释放对象内存的autoreleasePool就在其中提供了很好的帮助。另一方面是因为堆区是时刻变化的,如果我们使用了一个指针指向僵尸对象(一个已被释放内存的对象)并访问已被释放的内存,会造成crash(野指针报错导致),也就是软件崩溃。

认识MRC和ARC

我们再来认识一下MRC,毕竟在早期的Objective-C程序中,苹果开发者们都是使用MRC来手动管理对象的引用计数。

MRC,在ARC出现之前,Objective-C早期使用的是一种叫做MRC(Mannul Reference Counting)的手动管理内存的机制。通过键入上面所提到的retain、release、autorelease、retainCount等方法,开发者们能够手动控制对象引用计数的加1、减1等操作。

在MRC时期,熟练地运用引用计数这一机制,已经能为我们管理错综复杂的内存提供很好的帮助。但麻烦的是,我们仍要添加许多管理引用计数的代码,以确保对象在不被使用的情况下及时被释放,避免出现内存泄漏。

而添加管理引用计数的代码是一项繁琐的工作,我们需要注意release的数量是足够却又不会多出一两个的,指针指向对象后及时retain了对象或者release的时机是正确的,而不至于出现野指针错误等。要是没严格按照如下面一些指定的规范编写,漏了一个retain或release都会让我们觉得头大。

1.谁创建的谁release2.谁retain谁就release

对于这种繁琐而又固定的工作,作为开发者的我们应该想办法避免,把工作交给机器自动完成,进而达到解放双手,将更多精力放到思考( 摸鱼 )上面

以上是关于读书笔记系列—Objective-C中的内存管理的主要内容,如果未能解决你的问题,请参考以下文章

《Objective-C高级编程 iOS与OS X多线程和内存管理》读书笔记

读书笔记iOS-属性中的内存管理参数

《Effective Objective-C 2.0》读书/实战笔记 三

《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法》读书笔记(上)

《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法》读书笔记(上)

iOS开发系列—Objective-C之内存管理