iOS 記憶體管理機制

2021-06-27 14:10:33 字數 4006 閱讀 4408

學習要點:

1.  

reference

counting

引用計數機制

2. 了解mrc

,apc和gc

3.  

autoreleasepool

執行機制

4. 如何避免

retain cycle

reference counting

引用計數機制

cocoa

上基本的記憶體管理機制就是引用計數,通過乙個

reference count

(retaincount

)來計數,有乙個引用就加

1,釋放就減1,

reference count為0

,就釋放物件。

如果需要持有乙個物件,那麼對其傳送

retain

,如果之後不再使用該物件,那麼需要對其傳送

release

(或者autorealse

),每一次對

copy,retain,alloc

或者new

的呼叫,需要對應一次

release

或autorealse

呼叫。

alloc

就是開闢一塊記憶體,引用計數為1

new是較為老式的寫法

,後來引入了

alloc +init

這種寫法,

可以把分配記憶體和初始化操作分開。

assign

就是直接賦值,引用計數不變,當資料為

int, float

等原生型別時,可以使用

assign。

retain

引用計數加

1,返回乙個引用。

release

引用計數減

1,當引用計數為0時,

dealloc

函式被呼叫,記憶體被**。

copy

複製內容,在你不希望a和

b共享一塊記憶體時會使用到。a和

b各自有自己的記憶體。

nonatomic/atomic

表示該屬性是否是對多執行緒安全的,

atomic

會自動加

執行緒鎖,

但效率較差,

預設為atomic

什麼是mrc,

apc和gc

cocoa

上有三種記憶體管理機制,

mrc,

apc和gc,

gc由於效率問題從未在

ios是支援,目前基本已經不再使用,現在使用的主要是

mrc和

apc。

manual referecen counting(mrc)

即手動引用計數

,你需要手工維護所有的

retain

,release

計數,你必須確保他們一一對應。

automatic reference counting

,自動引用計數,

當arc

開啟時,編譯器將自動在**合適的地方插入

retain, release

和autorelease

。只需要像往常那樣編寫**,只不過不寫

retain,release

和autorelease

三個關鍵字就行。

strong

和weak

的區別

strong

和weak

是apc

中新加入的兩個屬性,

strong你可以簡單理解為擁有物件的所有權。只要該指標指向某個物件,那麼這個物件就不會被銷毀。反過來說,

arc的乙個基本規則即是,只要某個物件被任一

strong

指標指向,那麼它將不會被銷毀。如果物件沒有被任何

strong

指標指向,那麼就將被銷毀。

在預設情況下,所有的例項變數和區域性變數都是

strong

型別的。可以說

strong

型別的指標在行為上和

mrc時代

retain

的property

是比較相似的。

weak使用權指標。

weak

型別的指標指向物件,但是並不會持有該物件。

weak

另一特點是歸零,在乙個物件銷毀時在

arc機制作用下,所有指向這個物件的

weak

指標將被置為

nil。釋放不當造成的空指標是經常會碰到的問題,

是c/c++

使用多重指標的一種重要原因。使用

arc以後,不論是

strong

還是weak

型別的指標,都不再會指向乙個

dealloced

的物件,從根源上解決了意外釋放導致的

crash。

autoreleasepool要點

1.  autoreleasepool

核心是乙個佇列

,每當你呼叫

[blah autorelease]

是時候,系統會在

autoreleasepool

中註冊一下,當你呼叫

[poolrelease]

的時候,系統會負責給佇列中的每一項派發乙個

release。

2.  [autorelease]

是可以重複呼叫的,但你需要新增相應的

retain

來平衡。 3.

還有乙個新加入的方法

[pool drain]

,apc

下與release

相同,gc

下這個方法觸發強制**,而

[pool release]

是no-op。

4.老式的

autoreleasepool

看起來像這樣子,

nsautoreleasepool*pool = [[nsautoreleasepool alloc] init;

// codebenefitting from a local autorelease pool.

[poolrelease];

新式的寫法如下,這種方式更快,根據蘋果官方的說法

autoreleasepool

是nsautoreleasepool

的乙個例項,本質上應該沒有什麼變化,但更效率。

5. 一般來說main程式中有乙個autoreleasepool,每個執行緒都需要有乙個autoreleasepool。

同時,ui上每次事件處理時候開始的時候,ios會為我們自動生成乙個autorelesepool,事件結束的時候釋放掉。所以在事件處理中分配的物件在事件結束後就會釋放掉,釋放時間不確定。

6.在一些需要實時釋放的地方可以加乙個@autoreleasepool,當autoreleasepool中有大量的變數的時候是否回比較慢,最好拆分多個@autoreleasepool。

retain cycle

迴圈引用,典型的情況如下,

假設有三個物件,乙個父類的父類,乙個父類和乙個子類。父類的父類持有父類的引用(

retain

),父類持有子類的引用(

retain

),子類持有父類的引用(

retain

)。父類的父類釋放(

release

)父類,父類的父類

被釋放,而這時候父類和子類永遠保持

1的引用,游離在外。

解決retain cycle

的辦法就是

arc中使用

__weak

或__unsafe_unretained

弱引用。

iOS 記憶體管理機制

alloc 與 init 理解 myclass myobj myclass alloc init myclass myobj myclass alloc myobj myobj init alloc 分配了記憶體給物件,讓他不釋放,並且把位址返回給指標。但是這塊記憶體不能使用,因為沒有被正確的 初始...

iOS記憶體管理機制

todo cf和oc之間的轉換 core foundation框架和cocoa foundation框架區別 core foundation框架和foundation框架緊密相關,它們為相同功能提供介面,但foundation框架提供objective c介面。如果您將foundation物件和co...

談談 iOS 記憶體管理機制

從最簡單的 c 語言開始說起,c 語言中申請 malloc 到了一塊記憶體,你可以把這塊記憶體想象成乙個小球,你有根線牽著它,這根線就是指標,並且規定只有通過線才能拿到小球,乙個小球可以被很多人用線牽著.c 語言中釋放記憶體,就相當於把小球直接銷毀,但可能還有其他人用線牽著這個小球啊,當你釋放之後,...