IOS 記憶體管理,ios記憶體管理
軟體運行時會分配和使用裝置的記憶體資源,因此,在軟體開發的過程中,需要進行記憶體管理,以保證高效、快速的分配記憶體,並且在適當的時候釋放和回收記憶體資源。
IOS開發中,記憶體中的對象主要有兩類,一類是實值型別,比如int、float、struct等基礎資料型別 (Elementary Data Type),另一類是參考型別,也就是繼承自NSObject類的所有的OC對象。前一種實值型別不需要我們管理,後一種參考型別是需要我們管理記憶體的,一旦管理不好,就會產生非常糟糕的後果。
為什麼實值型別不需要管理,而參考型別需要管理呢?那是因為他們分配記憶體方式不一樣。
實值型別會被放入棧中,他們依次緊密排列,在記憶體中佔有一塊連續的記憶體空間,遵循先進後出的原則。參考型別會被放到堆中,當給對象分配記憶體空間時,會隨機的從記憶體當中開闢空間,對象與對象之間可能會留有不確定大小的空白空間,因此會產生很多記憶體片段,需要我們管理。
棧記憶體與堆記憶體從效能上比較,棧記憶體要優於堆記憶體,這是因為棧遵循先進後出的原則,因此當資料量過大時,存入棧會明顯的降低效能。因此,我們會把大量的資料存入堆中,然後棧中存放堆的地址,當需要調用資料時,就可以快速的通過棧內的地址找到堆中的資料。
實值型別和參考型別之間是可以相互轉化的,把實值型別轉化為參考型別的過程叫做裝箱,比如把int封裝為NSNumber,這個過程會增加程式的已耗用時間,降低效能。而把參考型別轉為實值型別的過程叫做拆箱,比如把NSNumer轉為float,在拆箱的過程中,我們一定要注意資料原有的類型,如果類型錯誤,可能導致拆箱失敗,因此會存在安全性的問題。手動的拆箱和裝箱,都會增加程式的已耗用時間,降低代碼可讀性,影響效能。
在IOS開發過程中,棧記憶體中的實值型別系統會自動管理,堆記憶體中的參考型別是需要我們管理的。每個OC對象內部都專門有四個位元組來儲存引用計數器,它是一個整數,表示對象被引用的次數,通過它可以判斷對象是否被回收,如果引用計數為0,對象回收,不為0不回收。當對象執行alloc、new或者retain時,引用計數加1,release時,引用計數減1。
Objective-c中提供了兩種記憶體管理機制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),分別提供對記憶體的手動和自動管理,來滿足不同的需求。MRC與ARC區別如所示。
1.MRC(人工引用計數),手動管理記憶體。
MRC模式下,所有的對象都需要手動的添加retain、release代碼來管理記憶體。使用MRC,需要遵守誰建立,誰回收的原則。也就是誰alloc,誰release;誰retain,誰release。
當引用計數為0的時候,必須回收,引用計數不為0,不能回收,如果引用計數為0,但是沒有回收,會造成記憶體泄露。如果引用計數為0,繼續釋放,會造成野指標。為了避免出現野指標,我們在釋放的時候,會先讓指標=nil。
2.ARC(自動引用計數),自動管理記憶體。
ARC是IOS5推出的新功能,通過ARC,可以自動的管理記憶體。在ARC模式下,只要沒有強指標(強引用)指向對象,對象就會被釋放。在ARC模式下,不允許使用retain、release、retainCount等方法。並且,如果使用dealloc方法時,不允許調用[super dealloc]方法。
ARC模式下的property變數修飾詞為strong、weak,相當於MRC模式下的retain、assign。strong :代替retain,預設關鍵詞,代表強引用。weak:代替assign,聲明了一個可以自動化佈建nil的弱引用,但是比assign多一個功能,指標指向的地址被釋放之後,指標本身也會自動被釋放。
strong :強引用,ARC中使用,與MRC中retain類似,使用之後,計數器+1。
weak :弱引用 ,ARC中使用,如果只想的對象被釋放了,其指向nil,可以有效避免野指標,其引用計數為1。
readwrite : 可讀可寫特性,需要產生getter方法和setter方法時使用。
readonly : 唯讀特性,只會產生getter方法 不會產生setter方法,不希望屬性在類外改變。
assign :賦值特性,不涉及引用計數,弱引用,setter方法將傳入參數賦值給執行個體變數,僅設定變數時使用。
retain :表示持有特性,setter方法將傳入參數先保留,再賦值,傳入參數的retaincount會+1。
copy :表示拷貝特性,setter方法將傳入對象複製一份,需要完全一份新的變數時。
nonatomic :非原子操作,不加同步,多線程訪問可提高效能,但是線程不安全的。決定編譯器產生的setter getter是否是原子操作。
atomic :原子操作,同步的,表示多安全執行緒,與nonatomic相反。
MRC與ARC理論上是不能相容的,也就是你如果建立的項目是ARC模式的,在你的代碼中是不能使用release,否則會出現記憶體問題。現在大部分程式都會選擇ARC的方式,但是很多第三方的架構是MRC模式,如果想把這些第三方的檔案加到自己項目中,需要進行標識,否則編譯的時候會出現錯誤。
在ARC的項目中,對MRC的檔案可以添加編譯選項-fno-objc-arc的標識;在MRC的項目中,對ARC的檔案可以添加編譯選項 -fobjc-arc的標識。 步驟如所示。
把MRC檔案轉為ARC,實際上是去掉檔案中的retain、release,因此也通過中方式完成。