學習要點:
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 語言中釋放記憶體,就相當於把小球直接銷毀,但可能還有其他人用線牽著這個小球啊,當你釋放之後,...