讀古今文學網 > iOS編程基礎:Swift、Xcode和Cocoa入門指南 > 12.2 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的指針也不會變成野指針。