我們知道,為了更加方便地處理內存管理問題,將開發人員從繁瑣的內存的分配和釋放工作中解放出來而專注於產品和邏輯,iOS提供了一種有效的方法,即自動引用計數ARC。采用了ARC之後,絕大部分內存管理的問題就不需要我們繼續操心了。但是從另一個方面講,這個方便的工具也助長了程序員的懶惰情緒,很多新手和學生甚至連引用計數的含義都不清楚。的確,這部分內容相對比較難以理解,不過如果能深刻地領悟之後將會是未來學習和開發中的強大助推器。
1、關於對象所有權的概念:
當一個所有者(可以是任意的objective-c對象)進行以下操作時,它就對某個對象擁有了所有權:創建或復制了某個對象,以及將對象保留使用。可能涉及到的函數有:
alloc; allocWithZone; copy; copyWithZone; mutableCopy; mutableCopyWithZone; retain;
如果某個所有者擁有某個對象的所有權,那麼該所有者有義務在適當的時刻釋放該對象:
release; autorelease;
在什麼時候需要著重考慮對象所有權?例如,某個對象(對象A)是另一個對象(對象B)的成員,而且子對象(A)與某個外部對象有關(比如通過外部對象對子對象進行設置)。此時需要著重考慮子對象創建和釋放的邏輯,防止出現提前釋放、誤釋放和未釋放等問題。
2、dealloc方法
作用:在引用計數為0的時候由系統自動調用,釋放當前對象並回收內存。通常重寫該函數以實現手動施放該對象中手動分配的成員。需要注意的是,由於子類的某些實例繼承自父類,因此在最後必須要調用父類的dealloc方法。
3、點語法的內存管理
在定義屬性property的時候通常會指定類型,如retain、assign等。主要考慮三個部分:
(1)賦值特性:assign——直接賦值(default);retain——保留對象,二者指向同一實例,引用計數+1;copy——拷貝對象,引用計數不變(少數情況下等價於retain);
(2)讀寫性:readwrite——可讀寫(default),生成setter和getter方法;readonly——只生成getter方法;
(3)原子性:atomic——原子類(default),開啟多線程保護;nonatomic——非原子類,不存在線程保護。
定義了property後,在使用點語法進行設置和讀取成員變量的時候會自動根據定義的類型進行相應的內存操作。
4、自動釋放池autorelease pool
在一個自動釋放池中創建的對象,可以被自動釋放。NSObject類提供了autorelease消息,向某個對象發送autorelease就可以將該對象加入自動釋放池。在自動釋放池銷毀的時候,會自動向池中的每一個對象發送一條release消息。
需要注意的一點是,自動釋放池並不能保證每一個池中的對象都成功施放。因為如果池中的對象引用計數大於1,則由於自動釋放池僅會發送一條release消息,因此該對象依然會存在。