iOS記憶體管理 一

2021-08-27 15:06:37 字數 3088 閱讀 5478

1. 內總管理原則(引用計數)

ios的物件都繼承於nsobject, 該物件有乙個方法:retaincount ,記憶體引用計數。 引用計數在很多技術都用到: window下的com元件,多執行緒的訊號量,讀寫鎖,思想都一樣。

(一般情況下: 後面會討論例外情況)

alloc 物件分配後引用計數為1

retain 物件的引用計數+1

copy copy 乙個物件變成新的物件(新記憶體位址) 引用計數為1 原來物件計數不變

release 物件引用計數-1 如果為0釋放記憶體

autorelease 物件引用計數-1 如果為0不馬上釋放,最近乙個個pool時釋放

nslog

(@"smessage retaincount:%u"

,[smessage

retaincount

]);[smessage retain]; //2

nslog(@"smessage retaincount:%u",[smessageretaincount]);

nslog(@"smessage retaincount:%u",[smessageretaincount]);

nslog

(@"smessage retaincount:%u"

,[smessage

retaincount

]);記憶體管理的原則就是最終的引用計數要平衡,

如果最後引用計數大於0 則會記憶體洩露

如果引用 計數等於0還對該物件進行操作,則會出現記憶體訪問失敗,crash 所以盡量設定為nil

這兩個問題都很嚴重,所以請一定注意記憶體釋放和不用過後設定為nil

2. autoreleasepool

每個工程都有乙個 main.m 檔案: 內容如下:

int main(int argc, char *argv)

很明顯c語言的main 函式:

nsautoreleasepool 是用來做autorelease 變數釋放的,前面說了, autorelease不會馬上釋放,當他到了最近的pool release 時會檢查reatin count 是不是為0, 為0就釋放。

當我們在一段**時加入了大量的autorelease變數時,我們應該為這段**加上

autoreleasepool,其它時候不用

在返回乙個物件時常常要返回乙個autorelease 物件,因為objectc 物件都是動態記憶體,沒有

棧的概念,所以不能像c/c++一樣返回乙個物件到棧,只能用autorelease物件。

3. 成員變數與屬性

實際情況並非上面那麼簡單,你可能需要在乙個函式裡呼叫另乙個函式分配的變數這時候

有兩個選擇: 類成員變數和使用屬性

@inte***ce testmem: nsobject

成員變數與上面的記憶體管理是一致的,只是在不同的函式裡要保持引用計數加減的平衡

所以要你要每次分配的時候檢查是否上次已經分配了。是否還能呼叫

什麼時候用屬性?

1. 把成員做為public.

2. outlet 一般宣告為屬性( 這個記憶體於系統控制,但我們還是應該做一樣操作,後面會講)

3. 如果很多函式都需要改變這個物件 ,或這個函式會觸發很多次,建議使用屬性。我們看看屬性函式展開後是什麼樣子:

// assign

-(void)settestobject :(id)newvalue

// retain

-(void)settestobject :(id)newvalue

}// copy

-(void)settestobject :(id)newvalue

}asssign 相於於指標賦值,不對引用計數進行操作,注意原物件不用了,一定要把這個設定為nil

retain 相當於對原物件的引用計數加1

copy 不對原物件的引用計數改變,生成乙個新物件引用計數為1

注意:self.testobject 左值呼叫的是settestobject 方法. 右值為get方法,get 方法比較簡單不用說了

而 真接testobject 使用的是成員變數

self.testobject = [[testobject alloc] init]; // 錯 reatin 兩次

testobject = [nsarray objectbyindex:0]; //錯

不安全,沒有retain 後面release會出錯

如果testobject已有值也會mem leak

4. 自動管理物件

ios 提供了很多static(+) 建立物件的類方法,這些方面是靜態的,可以直接用類名

呼叫如:

nsstring *teststring = [nsstring stringwithformat:@"test" ];

teststring 是自動管理的物件,你不用relese 他,他有乙個很大的retain count,release後數字不變。

5. 例外

有一些通過alloc 生成的物件相同是自動管理的如:

nsstring *teststring = [[nsstring alloc]initwithstring:@"test1"];

retain count 同樣是很大的數,沒辦法release

但為了**對應,還是應該加上[ teststring release];

不然xcode的analyze 會認識記憶體leak, 但instruments leak 工具檢測是沒有的

6.view 記憶體管理

通常我們程式設計會用到view, 在view 中的方法:

viewdidload

didreceivememorywarning

viewdidunload

@property (retain) nsarray *iarrtestmem

viewdidload

init retain is 0

(alloc) +1

=1if(memwarning)

didrecivememwarning -0=1

IOS 筆記 《一》 記憶體管理

footnote ps 學習ios很長時間了,一直沒總結過,以後盡量一周寫一篇。提到記憶體管理就要提mrr manual retain release 和arc automatic reference counting 先說mrr manual retain release oc建立物件原理 1.分...

ios記憶體管理

引用計數 每個物件有乙個與之相關的整數,稱作 引用計數器 或者 保留計數器 當某段 需要訪問乙個物件時,該段 會將物件的保留計數器 1,表示需要訪問這個物件 當結束對該物件的訪問時,保留計數器 1,表示它不在訪問該物件 當保留計數器為0時,物件被銷毀,所佔記憶體被系統收回。當使用new retain...

iOS記憶體管理

前提 1 以下是針對cocoa物件,不包括core foundation 2 cocoa物件都是用引用計數來跟蹤物件的記憶體使用情況的。3 在子類裡面父類先初始化和後釋放的原則。自己想下為什麼 棧空間和堆空間的區別。我們說的記憶體管理都是基於堆空間的,因為函式內的棧空間是由編譯器自己控制的。關於co...