iPhone內(nèi)存管理面面觀 對象所有權(quán)與引用計數(shù)
51CTO在前段日子采訪了國內(nèi)最牛的iPhone開發(fā)團隊,與各位一起走進了iOS開發(fā)。在iOS開發(fā)里,內(nèi)存管理是iPhone或iPad開發(fā)中最為重要的一部分。掌握好了內(nèi)存管理,開發(fā)出的應(yīng)用就能運行流暢;掌握不好,開發(fā)出的東西就會效率低下,且容易崩潰。本文詳細介紹iOS內(nèi)存管理的對象的所有權(quán)與引用計數(shù)。希望這些介紹會對開發(fā)者有所幫助。
當(dāng)一個所有者(owner,其本身可以是任何一個Objective-C對象)做了以下某個動作時,它擁有對一個對象的所有權(quán)(ownership):
1. 創(chuàng)建一個對象。包括使用任何名稱中包含“alloc”、“new”、或者“copy”的方法。
2. 保留(retain)一個對象。
一個對象可以有多個所有者,一個所有者也可以擁有多個對象。
相應(yīng)的,引用計數(shù)增減的基本規(guī)則是:
1.當(dāng)所有者創(chuàng)建一個對象時,該對象的引用計數(shù)為1。
2.當(dāng)所有者保留它時,該對象的引用計數(shù)加1。
3.當(dāng)所有者釋放(release)它時,該對象的引用計數(shù)減1。
與此相關(guān)的,當(dāng)一個所有者對于一個對象的引用計數(shù)的增減總計為0時,它放棄了對這個對象的所有權(quán)。
現(xiàn)在我們可以從兩個不同的角度來看Objective-C的內(nèi)存管理問題。從對象所有權(quán)的角度來看,當(dāng)一個對象有著至少一個所有者(owner)的時候,它依然存在;當(dāng)它沒有任何所有者的時候,它會被釋放掉。從引用計數(shù)的角度看,一個對象存在時,其引用計數(shù)大于零;當(dāng)一個對象的引用計數(shù)為零時,它會調(diào)用dealloc方法并釋放掉。這兩個角度的關(guān)系是:在所有權(quán)的背后起作用的機制是引用計數(shù)機制;我們通過引用計數(shù)的增減來理解所有權(quán)的概念;但是你只應(yīng)當(dāng)使用所有權(quán)的概念來管理內(nèi)存,因為如果你試圖直接獲取對象的引用計數(shù),那么得到的數(shù)將讓你感到匪夷所思——系統(tǒng)的一些框架會“偷偷”增減對象的引用計數(shù)。
回顧一下,內(nèi)存管理的目標(biāo)是:
當(dāng)一個對象的某個所有者依然需要使用它時,保證這個對象的存在;當(dāng)一個對象的所有所有者都不再需要它時,保證這個對象被銷毀。因此只要任何一個所有者在使用完一個對象之后釋放掉它,那么以上內(nèi)存管理的目標(biāo)就可以實現(xiàn)。
我們可以得出任何一個所有者(記住,所有者本身也只是一個對象)所應(yīng)當(dāng)遵守的基本步驟:
擁有一個對象 -> 使用一個對象 -> 放棄對象的所有權(quán)。
從引用計數(shù)的角度來看就是:
還需要這個對象時,保持對其增減為正;不再需要這個對象時,保持對其增減為0。
下圖很好地詮釋了這些基本規(guī)則:所有者1和所有者2單獨地執(zhí)行了擁有對象、使用對象、放棄對象所有權(quán)的步驟;當(dāng)所有者1不再需要該對象時及時放棄了所有權(quán),但此時所有者2依然擁有該對象,因此該對象依然存在,所有者2可以繼續(xù)使用它;當(dāng)所有者2也不再需要該對象時,也放棄掉所有權(quán),這時對象以不再有任何所有者(相應(yīng)的引用計數(shù)也變?yōu)?),因此立刻被銷毀掉。
引數(shù)計數(shù)的基本規(guī)則
需要注意的是,所有者2只是復(fù)制了該對象的指針,并沒有使用copy方法,因此復(fù)制指針這個操作本身并不增加對象的引用計數(shù);而正因為所有者2希望能使用該對象,因此通過retain方法成為它的所有者,也保證了所有者1放棄該對象時,對象不被銷毀。
原文地址:http://lichen1985.com/blog/?cat=10
【編輯推薦】