Objective-C 内存管理

栏目: Objective-C · 发布时间: 5年前

在 2011 年 WWDC(苹果全球开发者大会)的一场与 Objective-C 相关的讲座上,开发者的人生观被颠覆了。

作为一个开发者,管理好自己程序所使用的内存是天经地义的事,好比人们在溜狗时必须清理狗的排泄物一样(美国随处可见“Clean up after your dogs”的标志)。在本科阶段上 C 语言的课程时,教授们会向学生反复强调:如果使用 malloc 函数申请了一块内存,使用完后必须再使用 free 函数把申请的内存还给系统——如果不还,会造成“内存泄漏”的结果。这对于 Hello World 可能还不算严重,但对于庞大的程序或是长时间运行的服务器程序,泄内存是致命的。如果没记住,自己还清理了两次,造成的结果则严重得多——直接导致程序崩溃。

Objective-C 有类似 malloc/free 的对子,叫 alloc/dealloc,这种原始的方式如同管理C内存一样困难。所以 Objective-C 中的内存管理又增加了“引用计数”的方法,也就是如果一个物件被别的物件引用一次,则引用计数加一;如果不再被该物件引用,则引用计数减一;当引用计数减至零时,则系统自动清掉该物件所占的内存。具体来说,如果我们有一个字符串,当建立时,需要使用 alloc 方法来申请内存,引用计数则变成了一;然后被其他物件引用时,需要用 retain 方法去增加它的引用计数,变成二。当它和刚才引用的物件脱离关联时,需使 release 方法减少引用计数,又变回了一;最后,使用完这个字符串时,再用 release 方法减少其引用计数,这时,运行库发现其引用计数变为零了,则回收走它的内存。这是手动的方式。

这种方式自然很麻烦,所以又设计出一种叫做 autorelease 的机制(不是类似 Java 的自动垃圾回收)。在 Objective-C 中,设计了一个叫做 NSAutoReleasePool 的池,当开发者需要完成一个任务时(比如每开启一个线程,或者开始一个函数),可以手动创立一个这样的池子, 然后通过显式声明把物件扔进自动回收池中。NSAutoReleasePool 内有一个数组来保存声明为 autorelease 的所有对象。如果一个对象声明为 autorelease,则会自动加到池子里。如果完成了一个任务(结束线程了,或者退出那个函数),则开发者需对这个池子发送一个 drain 消息。这时,NSAutoReleasePool 会对池子中所有的物件发送 release 消息,把它们的引用计数都减一 ——这就好比游泳池关门时通知所有客人都“滚蛋”一样。所以开发者无需显式声明 release,所有的物件也会在池子清空时自动呼叫 release 函数,如果引用计数变成零了,系统才回收那块内存。所以这是个半自动、半手动的方式。

—《Mac OS X 背后的故事》


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法数论

算法数论

裴定一、祝跃飞 / 科学出版社 / 2002年09月 / 19.00

本书论述了算法数论的基本内容,其中包括:连分数、代数数域、椭圆曲线、素性检验、大整数因子分解算法、椭圆曲线上的离散对数、超椭圆曲线。本书的特点是内容涉及面广,在有限的篇幅内,包含了必要的预备知识和数学证明,尽可能形成一个完整的体系。并且本书的部分内容曾多次在中国科学院研究生院信息安全国家重点实验室和广州大学作为硕士研究生教材使用。 本书可作为信息安全、数论等专业的研究生教材及相关专业的研究人......一起来看看 《算法数论》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具