iOS關於記憶體管理的那點事兒

2021-08-17 22:14:03 字數 2879 閱讀 1878

ios記憶體管理從整體來講,就四點:

①自己生成的物件,自己持有;

②非自己生成的物件,自己也能持有;

③不再需要自己持有的物件時釋放;

④非自己持有的物件無法釋放。

在進行mrc記憶體管理時,我們需要注意幾點:

①自己生成的物件,自己持有,比如new/alloc/copy/mutablecopy建立;

②非自己生成的物件,自己也能持有,比如retain持有;

③不再需要自己持有的物件時釋放,用release釋放;

④非自己持有的物件無法釋放,比如物件release以後已經釋放,再次release會引起崩潰。

在進行arc記憶體管理時,我們需要注意幾點:

①block中迴圈引用問題;

②corefoundation和foundation框架橋接轉換;

③手動開闢的記憶體需要自己釋放;

④在類中,dealloc方法中對kvo和notification置為nil。

⑤不能顯示的呼叫retain、release、dealloc方法

⑥使用自動釋放池時,用@autoreleasepool塊來代替nsautoreleasepool物件。

⑦由於arc中記憶體管理是由編譯器來做的,而c語言中沒有方法來管理結構體成員的生命週期,所以oc中的變數不能作為c語言結構體的成員。

⑧在mrc中可以顯示的轉換id和void *,但是在arc中需要通過__bridge進行橋接轉換。

記憶體管理中的所有權修飾符分為四種:

__strong、__weak、__autorelease、__unsafe_unretained。前三個所有權修飾符可以保證初始化為nil,最後乙個所有權修飾符不能自動置為nil。

①__strong修飾符是id型別和物件型別預設的修飾符,__strong修飾符的引入,解決了mrc中需要手動release來解決記憶體管理問題。

②__weak修飾符用來打破迴圈引用,造成迴圈引用的情況有兩種,一種是物件間互相強引用,一種是物件對自身的強引用。

③__weak用於ios5以後打破迴圈引用,ios5之前使用__unsafe_unretained來打破迴圈引用,在arc中使用__unsafe_unretained時,該修飾符所修飾的物件,其記憶體不屬於編譯器的管理範圍。

④__unsafe_unretained修飾物件時,必須保證該物件沒有廢棄,否則可能引起崩潰。

__strong所有權修飾符:

①通過alloc初始化,偽**實現

id obj = objc_msgsend(obj, @selector(alloc));

obj_msgsend(obj, @selector(init));

obj_release(obj);

②通過類方法初始化,偽**實現

id obj = objc_msgsend(nsmutablearray, @selector(array));

objc_retainautoreleasedreturnvalue(obj);

objc_release(obj);

__weak所有權修飾符:

第一點:附有__weak修飾符的變數所引起的物件被廢棄,則將nil賦值給該變數。

id __weak obj1 = obj;

上面**,通過偽**實現

id obj1;

objc_initweak(&obj1,obj);

objc_destoryweak(&obj1);

定義函式objc_storeweak,把第二個引數的賦值物件的位址作為鍵值,將第乙個引數的附有__weak修飾符的變數的位址註冊到weak表中,如果第二個引數為0,則把變數的位址從weak表中刪除。

以上偽**,也可通過以下偽**實現

id obj1 = 1;

objc_storeweak(&obj1,obj);

objc_storeweak(&obj1,0);

weak表與引用計數表相同,都是作為雜湊表被實現。如果使用weak表,將廢棄物件的位址作為鍵值進行檢索,就能高速的獲取對應的附有__weak修飾符的變數位址。另外,由於乙個物件可同時賦值給多個附有__weak修飾符的變數中,所以乙個鍵值,可註冊多個變數的位址。

釋放weak修飾的物件時,程式的執行步驟分為四步:

①從weak表中獲取廢棄物件的位址為鍵值的記錄;

②將包含在記錄中的所有附有__weak修飾符變數的位址,賦值為nil;

③從weak表中刪除該記錄;

④從引用計數表中刪除廢棄物件的位址為鍵值的記錄。

第二點:附有__weak修飾符的變數,即是使用註冊到autoreleasepool中的物件

id __weak obj1 = obj;

nslog(@「%@」,obj1);

上面**通過偽**實現

宣告兩個函式,objc_loadweakretained函式取出附有__weak修飾符變數所引用的物件並retain,objc_autorelease函式將物件註冊到自動釋放池中。

id obj1;

objc_initweak(&obj1,obj);

id tmp = objc_loadweakretaind(&obj1);

objc_autorelease(tmp);

nslog(@「%@」,tmp);

objc_destoryweak(&obj1);

屬性修飾符中,assgin和unsafe_unretained的所有權修飾符是__unsafe_unretained、strong和retain、copy的所有權修飾符是__strong,weak的所有權修飾符是__weak。

關於iOS開發記憶體管理的那些事兒

1.在objc中物件是儲存在堆中的,系統並不會自動釋放堆中的記憶體 注意基本型別例如int,float是由系統自己管理的,放在棧上 2.我們可以通過dealloc方法來檢視是否乙個物件已經被 如果沒有被 則有可能造成記憶體洩露。如果乙個物件被釋放之後,那麼最後引用它的變數 我們手動設定為nil,否則...

iOS 螢幕方向那點事兒

一般的應用,只會支援豎屏正方向乙個方向,支援多個螢幕方向的應用還是比較少的。不過我在工作的專案中,跟這個螢幕方向接觸比較多,因為我們是乙個有介面的 sdk,要讓接入方接入的,一開始做沒什麼經驗,考慮到接入方本身的螢幕方向可能是多種的,所以我們直接上來就支援四個方向,然後就是各種轉屏的問題,90度旋轉...

記憶體那點兒事兒(一)

儲存程式文字,又稱文字段,指令指標從這裡獲得指令,可以被共享。用來儲存資料。分為初始化為非0的資料區,bbs block started by symbol 用來存放未初始化的全域性資料和靜態資料 和堆 heap 用來動態分配記憶體,就是說malloc等函式可以在這裡或的分配記憶體,位址是向上增長的...