記憶體管理機制,ios記憶體管理機制

來源:互聯網
上載者:User

記憶體管理機制,ios記憶體管理機制

Objective-C中提供了兩種記憶體管理機制MRC(MannulReference Counting)和ARC(Automatic Reference Counting),分別提供對記憶體的手動和自動管理,來滿足不同的需求.

 

ARC:

 

ARC是Auto Reference Counting的縮寫,即自動引用計數,由編譯器在代碼合適的位置中自動添加retain/Release/Autorelease/dealloc方法從而進行記憶體管理.

 

ARC幾個要點:

 

  • 在對象被建立時 retain count +1,在對象被release時 retain count -1.當retain count 為0 時,銷毀對象。
  • 程式中加入autoreleasepool的對象會由系統自動加上autorelease方法,如果該對象引用計數為0,則銷毀。

 

那麼ARC是為瞭解決什麼問題誕生的呢?這個得追溯到MRC手動記憶體管理時代說起。

 

MRC下記憶體管理的缺點:

 

  • 當我們要釋放一個堆記憶體時,首先要確定指向這個堆空間的指標都被release了。(避免提前釋放)
  • 釋放指標指向的堆空間,首先要確定哪些指標指向同一個堆,這些指標只能釋放一次。(MRC下即誰建立,誰釋放,避免重複釋放)
  • 模組化操作時,對象可能被多個模組建立和使用,不能確定最後由誰去釋放。
  • 多線程操作時,不確定哪個線程最後使用完畢

 

 

 

 

在ARC中與記憶體管理有關的標識符,可以分為變數標識符(_strong,  _weak, _unsafe_unretained, autoreleasing)和屬性標識符(nonatomic/atomic, assign/retain/strong/weak/unsafe_unretained/copy,readonly/readwrite),對於變數預設為__strong,而對於屬性預設為unsafe_unretained。也存在autoreleasepool。

 

 其中assign/retain/copy與MRC下property的標識符意義相同,strong類似與retain,assign類似於unsafe_unretained,strong/weak/unsafe_unretained與ARC下變數標識符意義相同,只是一個用於屬性的標識,一個用於變數的標識(帶兩個下劃短線__)。所列出的其他的標識符與MRC下意義相同。

 

(1)對於assign,你可以對標量類型(如int)使用這個屬性。你可以想象一個float,它不是一個對象,所以它不能retain、copy。

 

(2)對於copy,指定應該使用對象的副本(深度複製),前一個值發送一條release訊息。基本上像retain,但是沒有增加引用計數,是分配一塊新的記憶體來放置它。特別適用於NSString,如果你不想改變現有的,就用這個,因為NSMutableString,也是NSString。

 

 

 

MRC:

在MRC的記憶體管理員模式下,與對變數的管理相關的方法有:retain,release和autorelease。retain和release方法操作的是引用記數,當引用記數為零時,便自動釋放記憶體。並且可以用NSAutoreleasePool對象,對加入自動釋放池(autorelease調用)的變數進行管理,當drain時回收記憶體。

 

Strong 和 Weak 的區別:

強引用持有對象,弱引用不持有對象。 

強引用可以釋放對象,但弱引用不可以,因為弱引用不持有對象,當弱引用指向一個強引用所持有的對象時,當強引用將對象釋放掉後,弱引用會自動的被賦值為nil,即弱引用會自動的指向nil。

Strong 強引用,舉個例子:

1 id __strong test0 = [[NSObject alloc] init]; /* 設為對象A*/2 3 id __strong test1 = [[NSObject alloc] init];/*設為對象B*/

test0 和 test1 都是強引用,test0是對象A的持有人,就是擁有A,test1是對象B的持有人,就是擁有對象B,若:

test1 = test0;/*對象A的持有人就變成了test1*/

這樣對象B就沒有了持有人,沒有持有人的對象會被ARC回收,就是釋放,這樣:

test1持有對象A,test0也持有對象A。

 

weak 弱引用,主要作用是用來防治循環參考出現記憶體流失的問題,它主要是弱引用,弱引用就是不持有對象,只是指向這個對象,舉個例子:

1 id __strong test0 = [[NSObject alloc] init]; /* 設為對象A*/2 3 id __strong test1 = [[NSObject alloc] init];/*設為對象B*/4 5 id __weak test2 = test0;/*test1持有對象A的弱引用*/

test0持有對象A的強引用,而test2持有對象A的弱引用,也就是說,test0還是持有A的,而test2弱引用了test0的對象A,並沒有持有對象A,當test2離開了範圍,對對象A的引用就會失去,當對象A被釋放掉之後,test2會被置為nil,並不會出現crash。若:

test1 = test0;/*test1強引用對象A*/

此時對象B因為沒有持有人就會被釋放。

 

再如:

 1 #import <Foundation/Foundation.h> 2  3 int main(int argc, const char * argv[]) { 4     @autoreleasepool { 5         id __weak obj0 = nil; 6         if (YES) { 7             id obj1 = [[NSObject alloc] init];  //預設為強引用,即為strong類型 8             obj0 = obj1; 9             NSLog(@"obj0: %@", obj0);10         }11         NSLog(@"obj0: %@", obj0);12     }13     return 0;14 }15 16 /*17  *  輸出結果18  *  obj0: <NSObject: 0x1003066c0>19  *  obj0: (null)20  *21  *  因為obj1產生的預設的為強引用(__strong),在超出if的範圍之後,obj1所持有的對象被釋放,22  *  obj0為弱引用,所以obj0不持有對象,在obj1對象釋放後,obj0自動的被賦值為nil23  *  弱引用的特性是,不持有對象,即便是寫成id __weak obj1 = [[NSObject alloc] init];24  *  此代碼系統會給與警告,因為這裡obj1被聲明成弱引用,那麼在賦值之後,alloc出來的對象會被立即釋放。25  */

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.