iOS內存管理系列之一:對象所有權與引用計數

內存管理是iPhone或iPad開發中最爲重要的一部分。掌握好了內存管理,開發出的應用就能運行流暢;掌握不好,開發出的東西就會效率低下,且容易崩潰。從本文開始,我將分幾次詳細介紹iOS內存管理的方方面面,包括對象的所有權與引用計數、自動釋放與便捷方法、訪問器方法與屬性、一些會改變引用計數的特殊情況、以及一個總結。希望這些介紹會對開發者有所幫助。

本系列文章版權歸李晨所有,出版權歸華章公司所有,謝絕轉載。

-----對象所有權(ownership)與引用計數(retain count、reference count)-----

當一個所有者(owner,其本身可以是任何一個Objective-C對象)做了以下某個動作時,它擁有對一個對象的所有權(ownership):

1. 創建一個對象。包括使用任何名稱中包含“alloc”、“new”、或者“copy”的方法。

2. 保留(retain)一個對象。

一個對象可以有多個所有者,一個所有者也可以擁有多個對象。

相應的,引用計數增減的基本規則是:

1.當所有者創建一個對象時,該對象的引用計數爲1。

2.當所有者保留它時,該對象的引用計數加1。

3.當所有者釋放(release)它時,該對象的引用計數減1。

與此相關的,當一個所有者對於一個對象的引用計數的增減總計爲0時,它放棄了對這個對象的所有權。

現在我們可以從兩個不同的角度來看Objective-C的內存管理問題。從對象所有權的角度來看,當一個對象有着至少一個所有者(owner)的時候,它依然存在;當它沒有任何所有者的時候,它會被釋放掉。從引用計數的角度看,一個對象存在時,其引用計數大於零;當一個對象的引用計數爲零時,它會調用dealloc方法並釋放掉。這兩個角度的關係是:在所有權的背後起作用的機制是引用計數機制;我們通過引用計數的增減來理解所有權的概念;但是你只應當使用所有權的概念來管理內存,因爲如果你試圖直接獲取對象的引用計數,那麼得到的數將讓你感到匪夷所思——系統的一些框架會“偷偷”增減對象的引用計數。

回顧一下,內存管理的目標是:當一個對象的某個所有者依然需要使用它時,保證這個對象的存在;當一個對象的所有所有者都不再需要它時,保證這個對象被銷燬。因此只要任何一個所有者在使用完一個對象之後釋放掉它,那麼以上內存管理的目標就可以實現。我們可以得出任何一個所有者(記住,所有者本身也只是一個對象)所應當遵守的基本步驟:

擁有一個對象 -> 使用一個對象 -> 放棄對象的所有權。

從引用計數的角度來看就是:

還需要這個對象時,保持對其增減爲正;不再需要這個對象時,保持對其增減爲0。

下圖很好地詮釋了這些基本規則:所有者1和所有者2單獨地執行了擁有對象、使用對象、放棄對象所有權的步驟;當所有者1不再需要該對象時及時放棄了所有權,但此時所有者2依然擁有該對象,因此該對象依然存在,所有者2可以繼續使用它;當所有者2也不再需要該對象時,也放棄掉所有權,這時對象以不再有任何所有者(相應的引用計數也變爲0),因此立刻被銷燬掉。

需要注意的是,所有者2只是複製了該對象的指針,並沒有使用copy方法,因此複製指針這個操作本身並不增加對象的引用計數;而正因爲所有者2希望能使用該對象,因此通過retain方法成爲它的所有者,也保證了所有者1放棄該對象時,對象不被銷燬。


201008181121.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章