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等函式可以在這裡或的分配記憶體,位址是向上增長的...