【IOS學習基礎】記憶體管理

來源:互聯網
上載者:User

標籤:

1、記憶體幾大地區1> 棧區:局部變數(基礎資料型別 (Elementary Data Type)、指標變數)。2> 堆區:程式啟動並執行過程中動態分配的儲存空間(建立的對象)。3> BSS段:沒有初始化的全域變數和靜態變數。4> 資料區:已經初始化的全域變數和靜態變數。(字串常量)5> 程式碼片段:程式編譯後的代碼的內容。 2、引用計數器1> 引用計數器:每個繼承自NSObject的對象都有一個引用計數器,用來表示當前對象有幾個擁有者。2> 引用計數器的作用:用來判斷對象是否應該回收。3> 引用計數器的操作(ARC下無法使用) * retain  引用計數器+1
 * release  引用計數器-1 
 * retainCount 得到引用計數器的值(點擊進入NSObject.h檔案,有一個 - (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE 的方法) 註:任何一個OC對象,只要一被建立出來,其引用計數預設為1;一個對象的引用計數歸0的時候,對象就會被銷毀。 3、關於dealloc方法1> 對象被釋放時會自動調用2> 開發中經常重寫對象的dealloc方法,用於觀察對象什麼時候被釋放或者想要在對象釋放之前做些相應的操作,dealloc方法可以看做是對象的“臨終遺言”。3> 在MRC下,重寫dealloc要注意必須要在其最後調用[super dealloc]。 4、殭屍對象、野指標、null 指標。1> 殭屍對象:即指已經被銷毀的對象(不能再使用的對象)2> 野指標:指向殭屍對象(不可用記憶體)的指標,給野指標發送訊息會報“EXC_BAD_ACCESS"錯誤(常見錯誤)。3> null 指標:沒有指向儲存空間的指標(nil),給null 指標發送訊息沒有任何反應,試想一下,用nil調用方法怎麼可能有反應。而解決野指標錯誤的方法就是將對象的指標變為空白指標。
// 先開啟殭屍對象檢測         NSObject *obj = [[NSObject alloc] init];   [obj release];       // 野指標錯誤[obj log:@"測試"];


// 輸出台列印
2016-01-21 19:35:46.367 記憶體管理[2688:205046] *** -[NSObject log:]: message sent to deallocated instance 0x100113c80 (向一個已經被釋放的執行個體對象發送了訊息)
 5、開發中關於ARC(自動記憶體管理)和MRC(手動記憶體管理)的常用操作1> 將工程從ARC環境改為MRC環境(現在基本上都是ARC環境,保持預設即可)搜尋方塊中輸入“auto”將“YES”改為“NO”,即從ARC改為MRC了,反之改為“YES“就是從MRC改為ARC 2> 工程總體環境是ARC的,讓工程中某個類支援MRC開發中,我們有時候可能用到一些以前的類,而有些比較老的類庫又是MRC環境的,那麼可以選擇增加編譯開關"-fno-objc-arc”(這裡以GDataXMLNode類為例)除了關於“libxml.dylib”動態庫錯之外,初次將GDataXMLNode匯入工程的時候,會出現大約二十個錯誤,按照如操作即可   3> 檢測野指標(殭屍對象)錯誤    6、關於nil、Nil、NULL1> nil是一個對象值(對象為空白)  將對象等於nil。可以防止調用殭屍對象報錯2> Nil是一個類對象(類對象為空白)3> NULL是一個通用指標(泛型指標)4> [NSNull null]是一個對象,用在不能使用nil的場合。 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方法的名稱 8、NSString在記憶體管理中的問題
// 最近在網上視頻上看到的一個有趣的問題,按照視頻上所講        // 字串有一個常量池// 如果你需要的字串在常量池中已經存在了,不會分配記憶體空間// 使用字串的時候:採用下面1、3、5方式擷取的字串都在常量區(嗯,這三個NSString對象跟視頻上講的一樣,確實在字元常量區,因為列印其引用計數是一個巨大的數,所以判斷其記憶體不歸使用者管)        // 注意:視頻上所講,str2和str4的應該被分配在堆區,即記憶體歸使用者管,引用計數應該為1// 但事實上,看下面列印的str2和str4?瞬間淩亂了,Why,說好的在堆區呢?             NSString *str1 = @"abc";        NSString *str2 = [NSString stringWithFormat:@"aaa"];        NSString *str3 = [NSString stringWithString:@"abc"];        NSString *str4 = [[NSString alloc] initWithFormat:@"aaa"];        NSString *str5 = [[NSString alloc] initWithString:@"abc"];        NSString *str6 = [[NSString alloc] init];  // 在棧區?為啥它的引用計數那麼大?        NSLog(@"str1 = %@ , %p , %lu",str1,str1,str1.retainCount);        NSLog(@"str2 = %@ , %p , %lu",str2,str2,str2.retainCount);        NSLog(@"str3 = %@ , %p , %lu",str3,str3,str3.retainCount);        NSLog(@"str4 = %@ , %p , %lu",str4,str4,str4.retainCount);        NSLog(@"str5 = %@ , %p , %lu",str5,str5,str4.retainCount);        NSLog(@"str6 = %@ , %p , %lu",str6,str6,str5.retainCount);

// 列印

  2016-01-21 21:26:36.979 NSString記憶體管理問題[3269:255674] str1 = abc , 0x100004230 , 18446744073709551615

  2016-01-21 21:26:36.980 NSString記憶體管理問題[3269:255674] str2 = aaa , 0x61616135 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString記憶體管理問題[3269:255674] str3 = abc , 0x100004230 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString記憶體管理問題[3269:255674] str4 = aaa , 0x61616135 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString記憶體管理問題[3269:255674] str5 = abc , 0x100004230 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString記憶體管理問題[3269:255674] str6 =  , 0x7fff7c51bd00 , 18446744073709551615

  // 然後說在IOS項目下又不一樣,我姑且又試了一試,確實是記憶體位址不一樣了,但是引用計數是什麼鬼

  2016-01-21 21:30:42.632 NSString記憶體管理[3289:257683] str1 = abc , 0x106f4c050 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString記憶體管理[3289:257683] str2 = aaa , 0xa000000006161613 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString記憶體管理[3289:257683] str3 = abc , 0x106f4c050 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString記憶體管理[3289:257683] str4 = aaa , 0xa000000006161613 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString記憶體管理[3289:257683] str5 = abc , 0x106f4c050 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString記憶體管理[3289:257683] str6 =  , 0x107279380 , 18446744073709551615

  // 最後,我不死心,又試了一下

  NSArray *array1 = [[NSArray alloc] init];

  NSLog(@"array1 = %lu",array1.retainCount);

  NSMutableArray *array2 = [[NSMutableArray alloc] init];

  NSLog(@"array2 = %lu",array2.retainCount);

 // 列印 

  2016-01-21 21:48:01.828 NSString記憶體管理問題[3447:267148] array1 = 2  // 媽蛋  為什麼是2

  2016-01-21 21:48:01.828 NSString記憶體管理問題[3447:267148] array2 = 1

 // 最後

  看到最後,有這麼一張圖

  

    總結一下吧,不要相信retainCount的值。(不要用它去做判斷)

  平常都在用ARC,也沒注意到有這些問題,既然看到了,就權當瞭解一下。

    好記性不如爛筆頭!多多複習基礎知識,一一記錄下來還是有所收穫的!  

【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.