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).先建立一個可變數組對象,在建立一個可變字符串對象;spa

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

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

    ​    ​    ​(4)咱們爲何要用可變的字符串呢?稍後會提到爲何。對象

 

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

 

   ​    ​    運行的結果:內存

1
2
3
2014-08-03 19:53:24.449 Memory[2448:303] 新建str時的 strRetain = 1
2014-08-03 19:53:24.449 Memory[2448:303] 添加兩個str元素後 strRetain = 3
2014-08-03 19:53:24.450 Memory[2448:303] 移除一個元素後 strRetain = 2

 

    ​2.NSString的retainCount的變化ci

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

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

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

    ​    ​    ​    ​demo以下:

 

1
2
3
4
NSString *string = @ "aa" ;
NSLog(@ "str常量的retainCount = %d" ,( int )string.retainCount); //retainCount = -1
[string retain];  //沒用
NSLog(@ "str常量的retainCount = %d" ,( int )string.retainCount); //retainCount = -1

    ​    ​    ​運行結果:

1
2
2014-08-03 20:01:31.360 Memory[2463:303] str常量的retainCount = -1
2014-08-03 20:01:31.362 Memory[2463:303] str常量的retainCount = -1

 

 

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

    ​    ​    ​demo:

1
2
3
4
/*使用stringWithFormat建立的NSString爲變量,系統會進行引用計數。*/
NSString *string1 = [NSString stringWithFormat:@ "aaaa" ];
[string1 retain];
NSLog(@ "NSStringFomatRetainCount = %d" ,( int )string1.retainCount); //retainCount = 2

    ​    ​    ​運行結果:

1
NSStringFomatRetainCount = 2

 

 

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

    ​    ​    ​    ​demo:

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

 

    ​    ​    ​運行結果:

1
2
3
2014-08-03 20:18:37.240 Memory[2499:303] 傳入字符串常量 RetainCount = -1
2014-08-03 20:18:37.240 Memory[2499:303] 傳入的變量FomatRetainCount = 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表示弱引用。

相關文章
相關標籤/搜索