在编程语言中是少不了对内存的管理的,内存对于计算机来讲是宝贵的资源,因此对使用不到的资源进行回收是颇有必要的。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表示弱引用。