Objective-C中的內存管理

在編程語言中是少不了對內存的管理的,內存對於計算機來說是寶貴的資源,所以對使用不到的資源進行回收是很有必要的。OC中使用引用計數和垃圾回收來管理內存,在OC中爲每個對象分配一個引用計數器,當對象剛剛被創建時其初始值爲1,當有某段代碼需要訪問一個對象是時,會將該對象的引用計數器加1(通過retain來實現);當訪問一個對象結束時,會將該對象的引用計數器減1(通過release來實現);當計數器爲0時,該對象佔用的內存空間會被收回。在NSObject類有一個retainCount方法,調用該方法可獲取當前對象的引用計數值。

在XCode4以後的版本採取自動引用計數(Automatic Reference Counting)簡稱ARC, 默認的是ARC模式,在ARC下是不能直接調用retain,release, releaseCount等方法的,需要在XCode中進行設置,設置如下: 把Objective-C Automatic Reference Counting 改爲NO,即可。

​之前提到的NSOject類裏有個方法,retainCount可以獲取當前對象的引用計數的值,廢話少說上點代碼吧。

​    ​1. 用可變的數組結合着可變的字符串來觀察一下retainCount的變化。

​    ​    ​(1).先創建一個可變數組對象,在創建一個可變字符串對象;

​    ​    ​(2).然後往可變數組裏添加可變的字符串,觀察可變字符串的retainCount的變化。

​    ​    ​(3).在可變數組中移除一個str,觀察retainCount的變化

​    ​    ​(4)我們爲什麼要用可變的字符串呢?稍後會提到爲什麼。

[objc] view plaincopy
  1. <span style="font-size:18px;">//用可變數組來測試內存的訪問  
  2.   NSMutableArray *array = [NSMutableArray arrayWithCapacity:3];  
  3.   //可變的字符串  
  4.   NSMutableString *str = [[NSMutableString alloc] initWithString:@"aa"];  
  5.   //這時的retain = 1;  
  6.   NSLog(@"新建str時的 strRetain = %d",(int)[str retainCount]);  
  7.   
  8.   //把可變字符串對象傳入到可變數組中 NSMutalbe的retain會自動加一  
  9.   //把對象傳給另一個對象,此時的retain = 2;  
  10.   [array addObject:str];  
  11.   //retain =3;  
  12.   [array addObject:str];  
  13.   NSLog(@"添加兩個str元素後 strRetain = %d",(int)str.retainCount);  
  14.   
  15.   //移除元素  
  16.   [array removeObjectAtIndex:0];  
  17.   NSLog(@"移除一個元素後 strRetain = %d",(int)str.retainCount);</span>  

運行的結果:

[objc] view plaincopy
  1. <span style="font-size:18px;">2014-08-03 19:53:24.449 Memory[2448:303] 新建str時的 strRetain = 1  
  2. 2014-08-03 19:53:24.449 Memory[2448:303] 添加兩個str元素後 strRetain = 3  
  3. 2014-08-03 19:53:24.450 Memory[2448:303] 移除一個元素後 strRetain = 2</span>  

​2.NSString的retainCount的變化

​    ​    ​用NSString聲明的字符串變量的retainCount變化由你初始化字符串時的方式決定

​    ​    ​1. 用NSString *str = @”ludashi”;定義變量

​    ​    ​    ​用上面的方法定義的字符串是常量字符串,他的retianCount爲-1或不定,不會隨着retian或者release變化而變化

​    ​    ​    ​demo如下:

[objc] view plaincopy
  1. <span style="font-size:18px;">NSString *string = @"aa";  
  2. NSLog(@"str常量的retainCount = %d",(int)string.retainCount);//retainCount = -1  
  3. [string retain]; //沒用  
  4. NSLog(@"str常量的retainCount = %d",(int)string.retainCount);//retainCount = -1</span>  
            運行結果:

[objc] view plaincopy
  1. <span style="font-size:18px;">2014-08-03 20:01:31.360 Memory[2463:303] str常量的retainCount = -1  
  2. 2014-08-03 20:01:31.362 Memory[2463:303] str常量的retainCount = -1</span>  

​    ​    ​2.使用stringWithFormat創建的NSString爲變量,系統會進行引用計數。

​    ​    ​    ​​demo:

[objc] view plaincopy
  1. <span style="font-size:18px;">/*使用stringWithFormat創建的NSString爲變量,系統會進行引用計數。*/  
  2. NSString *string1 = [NSString stringWithFormat:@"aaaa"];  
  3. [string1 retain];  
  4. NSLog(@"NSStringFomatRetainCount = %d",(int)string1.retainCount);//retainCount = 2</span>  
​    ​    ​    ​運行結果:

[objc] view plaincopy
  1. <span style="font-size:18px;">NSStringFomatRetainCount = 2</span>  

​    ​    ​3 .stringWithString取決於後面跟的string, 後面string的retainCount是多少那麼用stringWithString創建的對象就爲多少

​    ​    ​    ​demo:

[objc] view plaincopy
  1. <span style="font-size:18px;">/*stringWithString取決於後面跟的string, 後面string的retainCount是多少那麼用stringWithString創建的對象就爲多少*/  
  2. NSString *string2 = [NSString stringWithString:string];  
  3. NSLog(@"傳入字符串常量 RetainCount = %d", (int)string2.retainCount);//retainCount = -1  
  4.   
  5. NSString *string3 = [NSString stringWithString:string1];  
  6. NSLog(@"傳入的變量FomatRetainCount = %d",(int)string1.retainCount);    //retainCount = 3  
  7. NSLog(@"傳入的變量RetainCount = %d", (int)string3.retainCount);//retainCount = 3</span>  

​    ​    ​    ​運行結果:

[objc] view plaincopy
  1. 2014-08-03 20:18:37.240 Memory[2499:303] 傳入字符串常量 RetainCount = -1  
  2. 2014-08-03 20:18:37.240 Memory[2499:303] 傳入的變量FomatRetainCount = 3  
  3. 2014-08-03 20:18:37.240 Memory[2499:303] 傳入的變量RetainCount = 3  

Objective-C中得ARC(Automatic Reference Counting)

​    1.​ARC中應注意的問題:

​    ​    ​(1). 不能顯式調用dealloc語句, 或者實現或調用retain, release, retianCount 和 autorelease等方法。

​    ​    ​(2).不能調用@selector (retain) ,@selector (release)等;

​    ​    ​(3).不能使用NSAutoreleasePool對象, 用@autoreleasepool塊來代替;

​    ​    ​(4).不能用開頭new的名稱來定義一個屬性,除非你定義一個別的getter名稱。

​    ​2.ARC特性

​    ​    ​ARC增加了新的屬性定義關鍵字,strong來代替retain,表示強引用。用weak來代替assign表示弱引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章