➢ 每個oc物件都有自己的引用計數器,是乙個整數,表示「物件被引用的次數」,即有多少人正在使用這個oc物件
➢ 每個oc物件內部專門有4個位元組的儲存空間來儲存引用計數器
引用計數器的作用
➢ 當使用alloc、new或者copy建立乙個新物件時,新物件的引用計數器預設就是1
➢ 當乙個物件的引用計數器值為0時,物件占用的記憶體就會被系統**。換句話說,如果物件的計數器不為0,那麼在整個程式執行過程,它占用的記憶體就不可能被**,除非整個程式已經退出
引用計數器的操作
➢ 給物件傳送一條retain訊息,可以使引用計數器值+1(retain方法返回物件本身)
➢ 給物件傳送一條release訊息,可以使引用計數器值-1
➢ 可以給物件傳送retaincount訊息獲得當前的引用計數器值
物件的銷毀
➢ 當乙個物件的引用計數器值為0時,那麼它將被銷毀,其占用的記憶體被系統**
➢ 當乙個物件被銷毀時,系統會自動向物件傳送一條dealloc訊息
➢ 一般會重寫dealloc方法,在這裡釋放相關資源,dealloc就像物件的遺言
➢ 一旦重寫了dealloc方法,就必須呼叫[super dealloc],並且放在最後面呼叫
➢ 不要直接呼叫dealloc方法
➢ 一旦物件被**了,它占用的記憶體就不再可用,堅持使用會導致程式崩潰(野指標錯誤)
2.記憶體管理原則
誰建立,誰release
➢ 如果你通過alloc、new或[mutable]copy來建立乙個物件,那麼你必須呼叫release或autorelease
➢ 換句話說,不是你建立的,就不用你去[auto]release
誰retain,誰release
➢ 只要你呼叫了retain,無論這個物件是如何生成的,你都要呼叫release
總結 ➢ 有始有終,有加就有減
➢ 曾經讓物件的計數器+1,就必須在最後讓物件計數器-1
dealloc方法的實現
4、 @property引數
1. 控制set方法的記憶體管理
➢ retain : release舊值,retain新值(用於oc物件)
➢ assign : 直接賦值,不做任何記憶體管理(預設,用於非oc物件型別)
➢ copy : release舊值,copy新值(一般用於nsstring *)
控制需不需生成set方法
➢ readwrite :同時生成set方法和get方法(預設)
➢ readonly :只會生成get方法
多執行緒管理
➢ atomic :效能低(預設)
➢ nonatomic :效能高
控制set方法和get方法的名稱
➢ setter : 設定set方法的名稱,一定有個冒號:
➢ getter : 設定get方法的名稱
5、 迴圈引用
1. @class
➢ 使用場景
對於迴圈依賴關係來說,比方a類引用b類,同時b類也引用a類
這種**編譯會報錯。當使用@class在兩個類相互宣告,就不會出現編譯報錯
➢ 用法概括
使用 @class 類名; 就可以引用乙個類,說明一下它是乙個類
➢ 和#import的區別
#import方式會包含被引用類的所有資訊,包括被引用類的變數和方法;@class方式只是告訴編譯器在a.h檔案中 b *b 只是類的宣告,具體這個類裡有什麼資訊,這裡不需要知道,等實現檔案中真正要用到時,才會真正去檢視b類中資訊
如果有上百個頭檔案都#import了同乙個檔案,或者這些檔案依次被#improt,那麼一旦最開始的標頭檔案稍有改動,後面引用到這個檔案的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方式就不會出現這種問題了
在.m實現檔案中,如果需要引用到被引用類的實體變數或者方法時,還需要使用#import方式引入被引用類
迴圈retain
➢ 比如a物件retain了b物件,b物件retain了a物件
➢ 這樣會導致a物件和b物件永遠無法釋放
解決方案
➢ 當兩端互相引用時,應該一端用retain、一端用assign
6、 autorelease
1. autorelease
➢ 給某個物件傳送一條autorelease訊息時,就會將這個物件加到乙個自動釋放池中
➢ 當自動釋放池銷毀時,會給池子裡面的所有物件傳送一條release訊息
➢ 呼叫autorelease方法時並不會改變物件的計數器,並且會返回物件本身
➢ autorelease實際上只是把對release的呼叫延遲了,對於每一次autorelease,系統只是把該物件放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有物件會被呼叫release
自動釋放池的建立
➢ ios 5.0後
@autoreleasepool
➢ ios 5.0前
nsautoreleasepool *pool = [[nsautoreleasepool alloc] init];
// …..
[pool release]; // 或[pool drain];
➢ 在程式執行過程中,可以建立多個自動釋放池,它們是以棧的形式存在記憶體中
➢ oc物件只需要傳送一條autorelease訊息,就會把這個物件新增到最近的自動釋放池中(棧頂的釋放池)
應用例項
➢ 跟release的對比
以前:
book *book = [[book alloc] init];
[book release];
現在:
book *book = [[[book alloc] init] autorelease];
// 不要再呼叫[book release];
➢ 一般可以為類新增乙個快速建立物件的類方法
+ (id)book
外界呼叫[book book]時,根本不用考慮在什麼時候釋放返回的book物件
規律 ➢ 一般來說,除了alloc、new或copy之外的方法建立的物件都被宣告了autorelease
➢ 比如下面的物件都已經是autorelease的,不需要再release
nsnumber *n = [nsnumber numberwithint:100];
nsstring *s = [nsstring stringwithformat:@」jack」];
nsstring *s2 = @」rose」;
Oc 記憶體管理
1 對你自己擁有的物件負責,你只能釋放你擁有的物件 2 凡是你通過 retain alloc copy等手段獲得了所有者的物件,都必須在你不使用的時候來呼叫release autorelease等手段來釋放對他的所有權 3 在一定的 段內,對同乙個物件所作的copy alloc retain的操作次...
OC記憶體管理
1.記憶體管理原則 如果對乙個物件使用了alloc mutable copy retain,那麼你必須使用相應的release或者autorelease。2.管理範圍 任何繼承了nsobject 的物件,對其他基本資料型別 int char float double struct enum等 無效 ...
OC 記憶體管理
管理範圍 任何繼承nsobject的物件,對其他的基本資料型別無效。判斷物件要不要 的唯一依據就是計數器是否為0,若不為0則存在。所以對記憶體的管理就是對計數器的管理 1 retain 計數器 1,會返回物件本身 2 release 計數器 1 沒有返回值 3 retaincount 獲取當前的計數...