iOS 記憶體管理

joker_king發表於2018-12-20

記憶體問題主要體現在兩個方面:記憶體溢位和野指標異常

記憶體的五大分割槽

棧區 系統開闢,系統釋放,不需要我們管理 堆區 程式設計師自己管理的空間,自己申請空間,自己釋放 靜態區 將定義變數的型別前加static,則變數的分配在靜態區 常量區 常量資料儲存在常量區,常量區的內容不可修改,block就存在於常量區 程式碼區 所有的語句編譯後生成的CPU指令儲存在程式碼區

引用計數機制

  • 在C語言中,使用molloc和free,進行記憶體的建立和釋放。
  • 實際開發中,可能會遇到兩個以上的指標使用同一塊記憶體。C語言無法記錄記憶體使用者的個數
  • OC中採用引用計數機制來管理記憶體,每個物件都有一個引用計數器,用來計算當前物件的引用次數
  • 當一個新的引用指向物件時,引用計數就加1,當去掉一個引用時,引用計數就減1.當引用計數到0時該物件的系統空間就會被回收。

引用計數

舉例說明:

  1. 第一個人進入辦公室的人,需要開燈“需要照明的人數”,計數值從0變成1.
  2. 之後每當有人進入辦公室,“需要照明的人數”就加1,此時計數值從1變成2.
  3. 每當有人下班離開辦公室,“需要照明的人數”就減1,計數值從2變成1.
  4. 最後一個人從下班離開辦公室,“需要照明的人數”減1,計數值從1變成0,因此關燈。 在OC中“物件”就相當於照明裝置,“開燈”就相當於生成物件,需要照明就相當於有別的物件需要持有當前物件,“不需要照明”就相當於要釋放物件的所有權,“關燈”就相當於發現當前物件沒有被任何別的物件持有,就把這個物件銷燬,也就是釋放掉這個物件所佔有的記憶體。

影響引用計數的方法

  • +alloc開闢記憶體空間,讓被開闢的記憶體空間的引用計數從0變為1.
  • -retain引用計數j加1,如果物件之前的引用計數為1,retain之後變為2.
  • -copy把某一物件的內容拷貝一份,原有物件的引用計數不變,新物件的引用計數變1.
  • -release引用計數立即減1

記憶體管理原則

  • 凡是使用了alloc,retain,或者copy讓記憶體的引用計數增加了,就需要使用release或者autorelease讓記憶體的引用計數減少,在一段程式碼內,增加和減少的次數要相等。
  • 如果增加的次數大於減少的次數,會造成記憶體洩漏。
  • 如果增加的次數小於減少的次數,會造成過度釋放。
  • 如果增加的次數等於減少的次數,還繼續訪問,造成野指標的問題。

修飾屬性的關鍵字

strong:強引用,ARC中使用,與MRC中的retain類似。 weak:弱引用,ARC使用,如果物件釋放了,則指標會指向nil,避免野指標。 assign:弱引用,基本上應用於基本資料型別。 copy:拷貝特性,物件拷貝,需遵循NSCoding協議mutableCopy是深拷貝,建立了一個一樣的物件。 readonly:只讀屬性,只生成getter方法,不生成setter方法。 atotic:原子特性,setter、getter方法在多執行緒訪問下是絕對安全的,也就是個setter、getter方法加了執行緒鎖,保證在同一時刻只有一個執行緒在訪問。 nonatotic:非原子特性,setter,getter方法內部不會做任何多執行緒的訪問處理,只是普通的setter、getter,方法。

相關文章