Objective-C 内存管理

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

在 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 背后的故事》


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

查看所有标签

猜你喜欢:

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

人工智能+:AI与IA如何重塑未来

人工智能+:AI与IA如何重塑未来

[美]韩德尔·琼斯(Handel Jones) [中]张臣雄 / 机械工业出版社 / 2018-10 / 55.00

当深度学习模型引发了全世界对人工智能的再次关注时,人工智能迎来第三次高速增长,人工智能(AI)、增强现实(AR)和虚拟现实(VR)正把人类带向新的“智能增强时代”(IA),我们将在不知不觉中接纳机器智能。 针对人类社会长期存在的众多复杂的动态的难题,人机融合智能将会提供全新的解决方案,谷歌、Facebook、微软、亚马逊、腾讯、阿里巴巴、百度等平台巨头纷纷斥千亿巨资布局人工智能的尖端技术;智......一起来看看 《人工智能+:AI与IA如何重塑未来》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

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

正则表达式在线测试