在编程语言中是少不了对内存的管理的,内存对于计算机来说是宝贵的资源,所以对使用不到的资源进行回收是很有必要的。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)我们为什么要用可变的字符串呢?稍后会提到为什么。

 


​//用可变数组来测试内存的访问​



​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);​


 

           运行的结果:


​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的变化

            用NSString声明的字符串变量的retainCount变化由你初始化字符串时的方式决定

            1. 用NSString *str = @"ludashi";定义变量

                用上面的方法定义的字符串是常量字符串,他的retianCount为-1或不定,不会随着retian或者release变化而变化

                demo如下:

 


​NSString *string = @​​ ​​"aa"​​ ​​;​



​NSLog(@​​ ​​"str常量的retainCount = %d"​​ ​​,(​​ ​​int​​ ​​)string.retainCount);​​ ​​//retainCount = -1​



​[string retain]; ​​ ​​//没用​



​NSLog(@​​ ​​"str常量的retainCount = %d"​​ ​​,(​​ ​​int​​ ​​)string.retainCount);​​ ​​//retainCount = -1​


            运行结果:


​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:


​/*使用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:


​/*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​


 

            运行结果:


​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表示弱引用。