在編程語言中是少不了對內存的管理的,內存對於計算機來講是寶貴的資源,因此對使用不到的資源進行回收是頗有必要的。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表示弱引用。