Objective-C學習筆記_記憶體管理(一)

來源:互聯網
上載者:User

標籤:objective-c   ios   記憶體管理   

一、記憶體管理的?式

大家都去過圖書館,而圖書館裡的書是可以借出的。我們來設想這樣一個情境,大家都去借書,但是從來沒有人去還書,那麼最後,這個圖書館會因為無書可借而倒閉,每個人都沒法再使用圖書館。電腦也是這樣,當程式運行結束時,作業系統將回收其佔用的資源。但是,只要程式運行就會佔用資源,如果不進行清理已經不用的資源,資源最終將被耗盡,程式將崩潰。

學會記憶體管理我們就明白什麼時候由你釋放對象,什麼時候你不能釋放。C語言中通過malloc、calloc、realloc和free搭配對記憶體進行管理。但是,C中的記憶體管理極易引起記憶體泄露和野指標異常(有關C語言記憶體泄露的問題,不是本博文的重點,對此不做過多贅述。詳情會在後續的博文中專門講解C記憶體問題。),而Objective-C對此進行了最佳化。

iOS應用程式出現Crash(閃退),90%以上的原因是記憶體問題。在一個擁有數?個甚至是上百個類的工程裡,尋找記憶體問題極其困難。瞭解記憶體常見問題,能幫我們減少出錯幾率。記憶體問題體現在兩個?面:記憶體溢出、野指標異常。

記憶體溢出

iOS給每個應?程式提供了一定的記憶體,?於程式的運行。iPhone 3GS記憶體30M左右,iPhone 5S記憶體80M左右。一旦超出記憶體上限,程式就會Crash。程式中最占記憶體的就是圖?、?頻、視頻等資源檔。3.5寸非Retina(視網膜)螢幕(320*480)放一張全屏圖片,佔用位元組數320*480*4(一個像素佔4個位元組,存放RGBA),即:600k Bytes。iPhone 3GS同時讀取60張圖片就會Crash。4寸螢幕(320*568),實際像素640*1136,程式存放一張全屏圖片,佔用位元組數640*1136*4,即2.77M Bytes。iPhone 5S同時讀取40張圖片就會Crash。

野指標異常

對象記憶體空間已經被系統回收,仍然使?指標操作這塊記憶體。野指標異常是程式crash的主要原因。代碼量越?的程式,越難找出野指標的位置。瞭解記憶體管理,能幫我們提升程式效能,?大減少調試bug時間。

記憶體管理的?式

記憶體回收(gc):程式員只需要開闢記憶體空間,不需要用代碼顯示地釋放,系統來判斷哪些空間不再被使用,並回收這些記憶體空間,以便再次分配。整個回收的過程不需要寫任何代碼,由系統自動完成記憶體回收。Java開發中一直使?的就是記憶體回收技術。

人工引用計數 MRC(Manual Reference Count):記憶體的開闢和釋放都由程式碼進?控制。相對記憶體回收來說,對記憶體的控制更加靈活,可以在需要釋放的時候及時釋放,對程式員的要求較高,程式員要熟悉記憶體管理的機制。

?動引用計數 ARC(Auto Reference Count):Xcode4.2及以上版本具有自動管理記憶體ARC機制,iOS 5.0的編譯器特性,它允許使用者只開闢空間,不用去釋放空間。它不是記憶體回收。本質是MRC,只是編譯器協助程式員預設加了釋放的代碼。

iOS的記憶體管理

  • iOS支援兩種記憶體管理方式:ARC 和 MRC。
  • MRC的記憶體管理機制是:引用計數。
  • ARC基於MRC。
二、記憶體管理機制及影響引用計數的方法引用計數

實際開發中,可能會遇到兩個以上的指標使用同一塊記憶體。C語言無法記錄記憶體使用量者的個數。Objective-C採用引用計數機制管理記憶體,當一個新的引用指向對象時,引用計數器就遞增,當去掉一個引用時,引用計數就遞減。當引用計數到零時,該對象就將釋放佔有的資源。

影響引?計數的方法

+ alloc:開闢記憶體空間,讓被開闢的記憶體空間的引用計數變為1。這是由0到1的過程。

- retain:引?計數加1,如果記憶體空間之前引用計數為1,retain之後變為2,如果引用計數是5,retain之後變為6。

- copy:把某一記憶體地區的內容拷貝一份,拷貝到新的記憶體空間裡去,被拷貝地區的引用計數不變,新的記憶體地區的引用計數為1。copy可以這樣理解,如果指標A和指標B不想互相牽扯,A管理A的記憶體,B管理B的記憶體。

- release:引用計數減1,如果記憶體空間之前引用計數為4,release之後變為3,如果之前引用計數為1,release之後變為0,記憶體被系統回收。

- autorelease:未來的某一時刻(程式運行出自動釋放池)引用計數減1。如果記憶體之前引用計數為4,autorelease之後仍然為4,未來某個時刻會變為3。

- dealloc:繼承自父類的方法,當對象引用計數為0的時候,由對象自動調用。在dealloc方法中對變數的釋放順序與初始化的順序相反,在最後調用[super init]。

autoreleasepool的使?

通過autoreleasepool控制autorelease對象的釋放。

向一個對象發送autorelease訊息,這個對象何時釋放,取決於autoreleasepool。

NSAutoreleasePool *pool= [[NSAutoreleasePool alloc] init];Person *p = [[Person alloc] init];  //  retainCount為1[p retain];  //  retainCount為2[p autorelease];  //  retainCount為2 未來的某個時刻釋放[pool release];  //  此時 autorelease的對象引用計數-1NSLog(@”%d”, [p retainCount]);  //  列印結果為1/* NSAutoreleasePool在ARC模式下運行,會得到編譯錯誤,而不是運行錯誤。作為替代,@autoreleasepool{}被引入。本例只是實現簡單效果。 */

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];[pool release];就像一對括弧,[xxx autorelease];必須寫在兩者之間。[xxx autorelease];出現在了兩者之間,pool就會把接收autorelease的對象給儲存起來(以棧的方式,把對象壓入棧)當[pool release];的時候,pool會向之前儲存的對象逐一發送release訊息(對象出棧,越晚autorelease的對象,越早接收release訊息)。

在iOS 5之後,不再推薦使用NSAutoreleasePool類,使用@autoreleasepool{}替代。之前寫在NSAutoreleasePool *pool = [[NSAutoreleasePool
alloc] init];
[pool release];之間的代碼,需要寫在@autoreleasepool{}的大括弧裡。出了大括弧,自動釋放池才向各個對象發送release訊息。

三、記憶體管理的原則

引用計數的增加和減少相等,當引用計數降為0之後,不應該再使?這塊記憶體空間。凡是使用了alloc、retain或者copy讓記憶體的引用計數增加了,就需要使用release或者autorelease讓記憶體的引?計數減少。在一段代碼內,增加和減少的次數要相等。

四、copy

跟retain不同,一個對象想要copy,?成?己的副本,需要實現NSCopying協議,定義copy的細節(如何copy)。如果類沒有接受NSCopying協議而給對象發送copy訊息,會引起crash。

copy分為深copy和淺copy。我們經常使用(包括下面例子)的是淺copy,至於區別會在後續的博文中詳細敘述。

copy?法的實現

Person.h?件

@interface Person : NSObject<NSCopying>@property (nonatomic, retain) NSString *name;@property (nonatomic, assign) int age;@end

Person.m?件

@implementation Person- (id)copyWithZone:(NSZone *)zone{  Person *p = [[Person allocWithZone:zone] init];  p.age = self.age;  p.name = self.name;  return p;}

main.m?件

Person *p = [[Person alloc] init];p.name = @”張三”;p.age = 20;Person *p2 = [p copy];//  p2是p的副本。p2.name與p.name一樣。p2.age與p.age一樣。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Objective-C學習筆記_記憶體管理(一)

相關文章

聯繫我們

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