MRC下的內(nèi)存管理

MRC下的內(nèi)存管理

內(nèi)存中的5大區(qū)域

  1. 棧區(qū)

這個區(qū)的內(nèi)存保存的是局部變量, 當(dāng)作用域結(jié)束后, 系統(tǒng)就會自動回收內(nèi)存.

局部變量num4 = 0x7fff5fbff7bc
  1. 堆區(qū)

這個區(qū)是用來程序員通過代碼來申請的空間, 這塊空間會一直保存到程序的結(jié)束, 直到程序員手動來釋放. 內(nèi)存管理只會管理堆區(qū)上的內(nèi)存.

對象小明在堆區(qū)的地址是:0x100400200
  1. BSS段

這個區(qū)的內(nèi)存主要是用來保存未被初始化的全局變量或靜態(tài)變量, 一旦被初始化后就會將數(shù)據(jù)轉(zhuǎn)移到數(shù)據(jù)段.同樣是系統(tǒng)自動執(zhí)行的.

  1. 數(shù)據(jù)段

這個區(qū)的內(nèi)存是用來保存全局變量或靜態(tài)變量, 直到程序結(jié)束才會被系統(tǒng)自動回收.

全局變量num1 = 0x1000011f0
靜態(tài)變量num3 = 0x1000011f4
類地址p1     = 0x1000011c8
  1. 代碼區(qū)

這個區(qū)的內(nèi)存是用來存儲程序中的代碼.

函數(shù)指針 p = 0x100000dd0

內(nèi)存管理的必要性

內(nèi)存中的對象如果不在不用的時候及時的回收, 可以想象對于有限的內(nèi)存來說是不可能實現(xiàn)的.

例如:iPhone的內(nèi)存警告機(jī)制, 內(nèi)存到40M就會警告, 如果到了120M就會閃退.

怎么進(jìn)行內(nèi)存管理

1.相關(guān)概念

如果想對內(nèi)存進(jìn)行管理, 首先必須理解與內(nèi)存管理相關(guān)的概念.

  • 僵尸對象與野指針

僵尸對象: 指的是內(nèi)存中的對象已經(jīng)被釋放, 但還沒有被CPU給分配出去.

野指針: C語言中的野指針指的是定義了一個指針但是沒有初始化, 導(dǎo)致指針中存儲的是垃圾值, 指向內(nèi)存中的任意地址.
OC中的野指針指的是指針指向的對象已經(jīng)被回收了, 如果仍有指針指向容易誤操作.

  • 內(nèi)存泄漏

內(nèi)存泄漏: 指的是一個應(yīng)該被回收的對象, 沒有得到及時的回收. 這樣的對象會一直存在于內(nèi)存中 直到程序結(jié)束. 這樣的結(jié)果會導(dǎo)致內(nèi)存的泄漏.

  • MRC與ARC

MRC: Manual Reference Counting, 指的是Xcode下編寫代碼需要手動對內(nèi)存進(jìn)行管理.

ARC: Automatic Reference Counting, 指的是Xcode下編寫代碼系統(tǒng)會自動的進(jìn)行內(nèi)存管理.

  • 引用計數(shù)器

引用計數(shù)器: 所有的OC對象內(nèi)都有一個叫做retainCount的屬性, 這個屬性的默認(rèn)值是1, unsigned long類型.

  • dealloc方法

dealloc方法: 所有的OC對象在被回收之前都會系統(tǒng)自動調(diào)用dealloc方法

2.內(nèi)存管理

  • 引用計數(shù)器的使用

引用計數(shù)器的默認(rèn)值是1, 調(diào)用類的retain方法使引用計數(shù)器+1, 調(diào)用類的release方法引用計數(shù)器-1. 當(dāng)引用計數(shù)器為0時, 對象就會被回收.

- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (oneway void)release OBJC_ARC_UNAVAILABLE;
  • 野指針與僵尸對象

為了避免野指針指向僵尸對象造成誤操作, 建議將在指針變成野指針后賦值為nil. 在Xcode下也可以打開僵尸對象檢查, 但是這樣會很影響程序的性能, 謹(jǐn)慎使用.

  • 內(nèi)存管理原則
  1. 有對象的創(chuàng)建就要匹配release.
Person *p1 = [Person new];
        
[p1 release];
  1. retain的次數(shù)要和release匹配.
Person *p1 = [Person new];
[p1 retain];
[p1 retain];
[p1 release];
[p1 release];
    
[p1 release];
  1. 為了代碼的規(guī)整, 誰用了一個對象誰就retain, 誰不用誰就release, 誰負(fù)責(zé)retain, 誰就負(fù)責(zé)release.

  1. 不要隨便retain, 多一個人使用的時候才retain, 少一個人使用的話就release.
  • 單個對象內(nèi)存管理
1. 有對象的創(chuàng)建 就必須要匹配1個release.
2. retain次數(shù)和release次數(shù)一定要匹配.
3. 只有在指針稱為野指針的時候才賦值為nil
4. 在方法中不要隨意的為傳入的對象retain.
  • 多個對象內(nèi)存管理
1.當(dāng)一個對象是另一個對象的參數(shù)時候, 重寫setter方法和dealloc方法
2.對象作為參數(shù)需要將舊的對象release, 新的對象retain
3.同一個對象作為參數(shù)被賦值了兩次時會造成內(nèi)存泄漏, 所以重構(gòu)setter方法的時候一定要加入if判斷新舊對象是否為同一個對象
重寫setter和dealloc的標(biāo)準(zhǔn)寫法
- (void)setCar:(Car *)car
     {
         if(_car != car)
         {
            [_car release];
            _car = [car retain];
         }
     }
     
     - (void)dealloc
     {
        [_car release];
        [super dealloc];
     }
  • @property參數(shù)
    MRC下:

a: 多線程相關(guān)

atomic: (默認(rèn)值)setter方法加了一把線程安全鎖, 效率低
nonatomic: 建議使用

b: 與生成setter方法的實現(xiàn)相關(guān)

assign: (默認(rèn)值) 生成的setter方法的實現(xiàn)就是直接賦值
retain: 生成的setter就是標(biāo)準(zhǔn)的MRC內(nèi)存管理管理代碼.ps:dealloc內(nèi)的release代碼還需要一樣寫

c: 與生成只讀, 讀寫屬性的相關(guān)

readwrite: (默認(rèn)值)代表同時生成getter和setter
readonly: 只生成getter, 不會生成setter

d: 與生成的getter, setter方法相關(guān)

getter=XXX: 重寫getter的方法名
setter=ooo: : 重寫setter方法的名字
在BOOL類型的參數(shù)中重寫getter
  • 類的循環(huán)引用
例如:Person類中有個Book類屬性, 而Book類中又有一個作者(Person)屬性. 這樣在導(dǎo)入頭文件的時候就會出現(xiàn)循環(huán)引用.

解決辦法:
其中一邊不要使用#import引入對方的頭文件.
而是使用@class 類名. 這樣就可以不引用對方頭文件的情況下, 告訴編譯器這是一個類.
@class
作用及含義: 相當(dāng)于向編譯器聲明了一個類, 并沒有實現(xiàn)它.(參考c語言的函數(shù)的聲明)

  • 對象間的相互引用
例如:Person類的小明對象有本書<三國>(Book類), <三國>對象有一個作者屬性是小明(Person類), 這個時候就出現(xiàn)了循環(huán)引用.

解決方法:
1端使用retain, 一端使用assign , assign那一邊就不需要release.

ARC下的內(nèi)存管理

ARC概述

Automatic Reference Couunting, 顧名思義是系統(tǒng)會自動幫助我們?nèi)ビ嬎阋糜嫈?shù)器的值, 是WWDC2011和iOS5引入的最大的變革和最激動人心的變化.ARC是新的LLVM3.0編譯器的一項特性,使用ARC,可以說一舉解決了廣大iOS開著所憎恨的手動管理內(nèi)存的麻煩.

ARC管理內(nèi)存的原理

  • 強(qiáng)指針與弱指針

默認(rèn)情況下, 我們聲明的指針就是強(qiáng)指針, 或者使用__strong來顯示的聲明一個強(qiáng)類型的指針.
弱指針指的是用__weak修飾的指針, 無論強(qiáng)指針還是弱指針, 作為存儲對象的地址, 并且通過指針操作對象方面上沒有任何區(qū)別, 唯一的區(qū)別是在對象回收上, 如果沒有任何強(qiáng)類型的指針指向的時候, 對象就會回收.

新建一個項目的話系統(tǒng)會默認(rèn)開啟ARC, 使用ARC的過程中, 系統(tǒng)會在編譯的過程中自動的在合適的位置為我們加上
retain, release, autorelease. 對象會在沒有強(qiáng)類型的指針指向的時候被回收掉, 其本質(zhì)還是對象的引用計數(shù)器被減為0了.

ARC與MRC的轉(zhuǎn)換和兼容

ARC和MRC通過命令-fno-objc-arc可以相互兼容, 通過Xcode可以將MRC手動轉(zhuǎn)成ARC, 由于系統(tǒng)的處理過于簡單, 謹(jǐn)慎使用.

ARC與垃圾回收機(jī)制的區(qū)別

垃圾回收機(jī)制GC是在程序的運行期間不斷循環(huán)掃描對象是否無人使用, 如果沒有使用就回收.
ARC是在程序編譯的過程就系統(tǒng)自動的加上了一些內(nèi)存管理代碼.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 內(nèi)存管理 簡述OC中內(nèi)存管理機(jī)制。與retain配對使用的方法是dealloc還是release,為什么?需要與a...
    丶逐漸閱讀 2,081評論 1 16
  • iOS內(nèi)存管理 概述 什么是內(nèi)存管理 應(yīng)用程序內(nèi)存管理是在程序運行時分配內(nèi)存(比如創(chuàng)建一個對象,會增加內(nèi)存占用)與...
    蚊香醬閱讀 5,813評論 8 119
  • 內(nèi)存管理 ARC處理原理 ARC是Objective-C編譯器的特性,而不是運行時特性或者垃圾回收機(jī)制,ARC所做...
    b485c88ab697閱讀 11,347評論 3 47
  • 為什么進(jìn)行內(nèi)存管理? 由于移動設(shè)備的內(nèi)存極其有限,所以每個APP所占的內(nèi)存也是有限制的,當(dāng)app所占用的內(nèi)存較多時...
    天天想念閱讀 977評論 1 6
  • 別人口中說出來的又或者看到的,都不一定是真實的你,所以……我只相信自己去了解的,不屑于去打聽又或者試探什么
    0雲(yún)閱讀 116評論 0 0

友情鏈接更多精彩內(nèi)容