objective-C基礎教程(第2版)-第九章筆記
技術標籤:IOS
OC記憶體管理
cocoa採用引用計數進行記憶體管理,即當訪問一個物件是該物件的保留計數器值+1,當結束訪問後物件的保留計數器-1
當使用alloc,new
方法或通過copy訊息建立一個物件是,物件的保留計數器值設定為1,改變這個值可以通過傳送retain
訊息+1, release
訊息-1
當一個物件的保留計數器歸0即將銷燬時,oc會自動向物件傳送一條關於dealloc
的訊息
[obj retain]; // 保留數 + 1
[obj release]; // 保留數 - 1
[obj retainCount]; // 獲取保留數
OC的自動釋放池
NSObject
提供了一個叫做autorelease
release
訊息,其返回值是接收這條訊息的物件,當對該物件傳送autorelease
訊息時實際上是將該物件新增到自動釋放池中,當自動釋放池被銷燬時將向該池中的所有物件傳送release
訊息oc中可通過
@autoreleasepool
(推薦)或NSAutoreleasePool
物件建立一個自動釋放池
// 花括號中的程式碼將會被放入新池子中;推薦關鍵字方法,比物件更
關鍵字方法 @autoreleasepool{}
// 建立和釋放該物件之間的程式碼會使用新池子
物件NSAutoreleasePool
自動釋放池以棧的形式實現,新建立的自動釋放池會被新增到棧頂,接收autorelease
ARC自動引用計數,ARC會最終你的物件並在編譯器中幫你插入retain和release,ARC不是垃圾回收器
在程式碼中使用ARC需滿足以下三個條件
- 能明確哪些物件需要進行記憶體管理
如C型陣列不是可保留物件使用無法使用ARC特性
- 能表明如何去管理物件
必須能對某個物件的保留計數器進行+1或-1的操作,也就是說NSObject類的子類都能進行記憶體管理
- 有可行的辦法傳遞物件所有權
傳遞物件是,你的程式必須能夠在呼叫者和接收者之間傳遞所有權
當用指標指向某個物件時,你管理它的記憶體就擁有該物件的強引用,如果沒有管理則擁有的是弱引用
當出現迴圈引用時,如下圖,持有一個A物件,A物件內部持有一個B物件,同時B物件又擁有指向A的引用,則當外部不再指向A物件時,會導致A,B物件由於迴圈引用的問題沒有被釋放,因此需要弱引用來破解
將B指向A的引用改為弱引用,因為是弱引用所以保留計數器的值不會增加,當外部釋放A時提示也會釋放B
但是當三個物件相互引用如下圖時
當A釋放了B時,C仍將擁有B的弱引用,直接使用它會導致問題,其指向的地方已經沒有有效值了。這種情況的解決方案為讓物件自己去清空弱引用的物件,這種特殊的弱引用被稱為歸零弱引用,當指向的物件釋放後,這些若引用會被設為零(nil)
歸零弱引用的使用
宣告變數是使用__weak關鍵字或對屬性使用weak特性@property(weak)
同樣強引用可以用__strong或strong特性
ARC和垃圾回收機制無法一同使用
異常NSException
OC中的異常處理感覺沒太大用處,因為異常處理無法捕捉記憶體洩露引起的崩潰,而這也是iOS應用中最常重新的崩潰,所以就大致記錄下
丟擲異常可以用@throw
異常物件或[異常物件 raise]
,但兩者不能同時使用,raise只對NSException
物件有效,而@throw
可以用在其他物件上。
在@catch
異常代理程式碼中可以直接使用@throw
重複丟擲異常而無需指定異常物件
@try
建立一次不會產生消耗單捕捉異常會消耗大量的資源並影響程式執行的速度,另外異常也需要記憶體管理