首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》12.2 Cocoa内存管理的原则

关灯直达底部

如果一个对象能够遵循一些简单且明确的原则,符合内存管理的基本概念,那么它在内存管理上就不会出现什么问题。其本质是如果某个对象拥有对另外一个引用类型对象的引用,那么它只会负责自己那一部分的内存管理工作,这符合上述原则。如果拥有该引用类型对象引用的所有对象都能按照这些原则行事,那么该对象的内存就会被正确地管理,并且在不需要时被精确地销毁。

考虑这3个对象:Manny、Moe与Jack。Jack是我们的目标对象:我们来管理他的内存,如果Jack的内存被正确管理,那么它就会被正确地销毁。Manny与Moe会参与到Jack内存的管理工作中。他们是如何做到这一点的呢?只要Manny与Moe遵循如下原则,那就会万事大吉:

·如果Manny或Moe显式实例化了Jack(通过直接调用初始化器),那么该初始化器就会增加Jack的保持计数。

·如果Manny或Moe创建了Jack的一个副本(通过调用copy、copyWithZone:、mutableCopy或其他名字中带有copy的方法),那么复制方法就会增加这个新创建的Jack副本的保持计数值。

·如果Manny或Moe获得了对Jack的引用(不是通过显式的实例化或复制),并且要求Jack一直存在(比如,可以通过代码使用Jack,或让Jack作为一个实例属性值),那么他本身就会增加Jack的保持计数(这叫作保持Jack)。

·如果只有Manny或Moe自身做了上面这些事情(即Manny或Moe直接或间接地导致Jack的保持计数增加了),那么当他自身不再需要引用Jack时,在释放对其的引用前,他会减少Jack的保持计数,从而平衡之前对保持计数的增加值(这叫作释放Jack)。释放掉Jack后,Manny与Moe就会认为Jack已经不复存在了,因为如果这导致Jack的保持计数归0,那么Jack就不复存在了。这是内存管理的黄金法则,这个原则会让内存管理一致且正确地工作。

理解内存管理黄金法则的一般做法是从所有权角度进行思考。如果Manny创建、复制或保持了Jack(也就是说,Manny增加了Jack的保持计数),那么Manny就宣称了对Jack的所有权。Manny与Moe可以同时拥有对Jack的所有权,不过每个人都只负责正确管理自己对Jack的所有权。最终减少Jack的保持计数是Jack的每个所有者的职责,释放Jack,从而释放了对Jack的所有权。拥有者会说:“在这儿之后,Jack可能存在,也可能不复存在,不过对于我来说,我已经使用完了Jack,就我而言,Jack已经销毁了。”与此同时,非Jack的所有者永远也不会释放Jack。只要所有对象都是这样处理Jack的,那么Jack就永远不会出现内存泄漏,指向Jack的指针也不会变成野指针。