IOS記憶體管理詳解

來源:互聯網
上載者:User

標籤:bubuko   情境   整數   nsobject   5.0   ble   類型   property   重寫   

一、    基本原理

 

1.        什麼是記憶體管理
  • 行動裝置的記憶體極其有限,每個app所能佔用的記憶體是有限制的
  • 當app所佔用的記憶體較多時,系統會發出記憶體警告,這時得回收一些不需要再使用的記憶體空間。比如回收一些不需要使用的對象、變數等
  • 管理範圍:任何繼承了NSObject的對象,對其他基礎資料型別 (Elementary Data Type)(int、char、float、double、struct、enum等)無效

 

2.        對象的基本結構

  • 每個OC對象都有自己的引用計數器,是一個整數,表示“對象被引用的次數”,即有多少人正在使用這個OC對象
  • 每個OC對象內部專門有4個位元組的儲存空間來儲存引用計數器

 

3.        引用計數器的作用
  • 當使用alloc、new或者copy建立一個新對象時,新對象的引用計數器預設就是1
  • 當一個對象的引用計數器值為0時,對象佔用的記憶體就會被系統回收。換句話說,如果對象的計數器不為0,那麼在整個程式運行過程,它佔用的記憶體就不可能被回收,除非整個程式已經退出

 

4.        引用計數器的操作
  • 給對象發送一條retain訊息,可以使引用計數器值+1(retain方法返回對象本身)
  • 給對象發送一條release訊息,可以使引用計數器值-1
  • 可以給對象發送retainCount訊息獲得當前的引用計數器值

 

5.        對象的銷毀
  • 當一個對象的引用計數器值為0時,那麼它將被銷毀,其佔用的記憶體被系統回收
  • 當一個對象被銷毀時,系統會自動向對象發送一條dealloc訊息
  • 一般會重寫dealloc方法,在這裡釋放相關資源,dealloc就像對象的遺言
  • 一旦重寫了dealloc方法,就必須調用[super dealloc],並且放在最後面調用
  • 不要直接調用dealloc方法
  • 一旦對象被回收了,它佔用的記憶體就不再可用,堅持使用會導致程式崩潰(野指標錯誤)

 

二、    Xcode的設定1.     取消ARC

要想手動調用retain、release等方法,在建立項目的時候不要勾選ARC

 

2.     開啟殭屍對象監控

預設情況下,Xcode是不會管殭屍對象的,使用一塊被釋放的記憶體也不會報錯。為了方便調試,應該開啟殭屍對象監控

     

           

 

 

三、    記憶體管理原則1. 原則分析
  • QQ堂開房間原理:只要房間還有人在用,就不會解散
  • 只要還有人在用某個對象,那麼這個對象就不會被回收
  • 只要你想用這個對象,就讓對象的計數器+1
  • 當你不再使用這個對象時,就讓對象的計數器-1

 

 

2. 誰建立,誰release
  • 如果你通過alloc、new或[mutable]copy來建立一個對象,那麼你必須調用release或autorelease
  • 換句話說,不是你建立的,就不用你去[auto]release

 

3. 誰retain,誰release
  • 只要你調用了retain,無論這個對象是如何產生的,你都要調用release

 

4. 總結
  • 有始有終,有加就有減
  • 曾經讓對象的計數器+1,就必須在最後讓對象計數器-1

 

四、    set方法的記憶體管理

如果你有個OC物件類型的成員變數,就必須管理這個成員變數的記憶體。比如有個Book *_book

1.        set方法的實現
- (void)setBook:(Book *)book{       if (book != _book) {           [_book release];           _book = [book retain];       }}

 

 

 

2.        dealloc方法的實現
1 - (void)dealloc {2 3        [_book release];4 5        [super dealloc];6 7 }

 

 

 

五 @property參數1.  控制set方法的記憶體管理
  • retain : release舊值,retain新值(用於OC對象)
  • assign : 直接賦值,不做任何記憶體管理(預設,用於非OC物件類型)
  • copy   : release舊值,copy新值(一般用於NSString *)

 

2. 控制需不需產生set方法
  • readwrite :同時產生set方法和get方法(預設)
  • readonly  :只會產生get方法

 

3. 多線程管理
  • atomic:效能低(預設)
  • nonatomic :效能高

 

4. 控制set方法和get方法的名稱
  • setter : 設定set方法的名稱,一定有個冒號:
  • getter : 設定get方法的名稱

 

六、循環參考1. @class
  • 使用情境

對於循環相依性關係來說,比方A類引用B類,同時B類也引用A類

          

這種代碼編譯會報錯。當使用@class在兩個類相互聲明,就不會出現編譯報錯

  • 用法概括

使用 @class 類名; 就可以引用一個類,說明一下它是一個類

  • 和#import的區別

l   #import方式會包含被引用類的所有資訊,包括被引用類的變數和方法;@class方式只是告訴編譯器在A.h檔案中 B *b 只是類的聲明,具體這個類裡有什麼資訊,這裡不需要知道,等實現檔案中真正要用到時,才會真正去查看B類中資訊

l   如果有上百個標頭檔都#import了同一個檔案,或者這些檔案依次被#improt,那麼一旦最開始的標頭檔稍有改動,後面引用到這個檔案的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方式就不會出現這種問題了

l   在.m實現檔案中,如果需要引用到被引用類的實體變數或者方法時,還需要使用#import方式引入被引用類

 

 

2. 迴圈retain
  • 比如A對象retain了B對象,B對象retain了A對象
  • 這樣會導致A對象和B對象永遠無法釋放

 

3.  解決方案
  • 當兩端互相引用時,應該一端用retain、一端用assign

 

七、  autorelease1.        autorelease
  • 給某個對象發送一條autorelease訊息時,就會將這個對象加到一個自動釋放池中
  • 當自動釋放池銷毀時,會給池子裡面的所有對象發送一條release訊息
  • 調用autorelease方法時並不會改變對象的計數器,並且會返回對象本身
  • autorelease實際上只是把對release的調用延遲了,對於每一次autorelease,系統只是把該對象放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有對象會被調用Release

 

2.        自動釋放池的建立
  • ios 5.0後

@autoreleasepool

{

    // ....

}

  • ios 5.0前

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// .....

[pool release]; // 或[pool drain];

  • 在程式運行過程中,可以建立多個自動釋放池,它們是以棧的形式存在記憶體中
  • OC對象只需要發送一條autorelease訊息,就會把這個對象添加到最近的自動釋放池中(棧頂的釋放池)

 

3.        應用執行個體
  • 跟release的對比

l   以前:

 

Book *book = [[Book alloc] init];[book release];

 

 

l   現在:

Book *book = [[[Book alloc] init] autorelease];

 

// 不要再調用[book release];

 

  • 一般可以為類添加一個快速建立對象的類方法
+ (id)book {    return [[[Book alloc] init] autorelease];}

 

 

外界調用[Book book]時,根本不用考慮在什麼時候釋放返回的Book對象

 

4.        規律
  • 一般來說,除了alloc、new或copy之外的方法建立的對象都被聲明了autorelease
  • 比如下面的對象都已經是autorelease的,不需要再release
NSNumber *n = [NSNumber numberWithInt:100];NSString *s = [NSString stringWithFormat:@"jack"];NSString *s2 = @"rose";

IOS記憶體管理詳解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.