讀古今文學網 > iOS編程基礎:Swift、Xcode和Cocoa入門指南 > 12.4 Cocoa對像管理內存的方式 >

12.4 Cocoa對像管理內存的方式

如果需要,那麼內建的Cocoa對像會通過保持來獲得你傳遞給它們的對象的所有權,當然,接下來會通過釋放來平衡之前的保持。實際上,這是非常普遍的情況;如果Cocoa對像沒有保持你傳遞給它的對象,那麼文檔中會有相應的說明。

集合(如NSArray或NSDictionary)就是個顯而易見的示例(參見第10章關於常見集合類的介紹)。如果一個對象可以在任意時刻銷毀,那麼它幾乎無法成為集合的元素;因此,在向集合中添加元素時,集合會通過保持來聲明對該對象的所有權。接下來,集合就成為一個功能良好的所有者。如果是可變集合,並且其中的元素被刪除了,那麼集合就會釋放該元素。如果集合對像銷毀了,那麼它會釋放其中的所有元素。

在ARC之前,從可變集合中刪除對像存在一個潛在的陷阱。考慮如下Objective-C代碼:


id obj = myMutableArray[0];
[myMutableArray removeObjectAtIndex: 0]; // bad idea in non-ARC code!
// ... could crash here by referring to obj ...,
  

如前所述,在從可變集合中刪除對像時,集合會釋放它。因此,上述示例中被註釋的一行涉及對myMutableArray中元素0對象的隱式釋放。如果將對象的保持計數減為0,那麼它就會被銷毀。指針obj就會變成一個野指針,在將其當作實際對像使用時會導致應用崩潰。

不過在ARC中,這種危險情況已經不復存在。將一個引用類型的對象賦給一個變量時會保持它!這樣,代碼就變得安全了,下面是與之等價的Swift代碼:


let obj = myMutableArray[0]
myMutableArray.removeObjectAtIndex(0)
// ... safe to refer to obj ...
  

第1行會保持對象,第2行會釋放對象,不過這個釋放會平衡掉之前將對像放到集合中時對該對象的保持。這樣,對象的保持計數依舊大於0,它會在代碼執行期間繼續存活。