IOS第六天——Obj-C的内存管理初步认识

来源:互联网 发布:课表安排软件 编辑:程序博客网 时间:2024/05/21 09:49

转:http://blog.csdn.net/jeepxiaozi/article/details/8821747

今天是学习IOS开发的第六天,那么因为看的比较快,所以现在应该到了IOS开发中的重中之重了,那就是内存管理。

Obj-C中的内存管理不同于C语言式的完全手动管理方式,malloc和free操控内存,也不同于GC语言(例如java&ruby等)的自动回收方式,在Obj-C中的内存管理方式采用的是比较折中的方式,也就是手动和半自动结合,采用自动对象释放池进行自动管理或者采用引用计数值进行手动管理。

1.      引用计数值

至于为什么要进行内存管理,这里我想大家应该基本了解了,即使我这种不太了解底层的码畜都知道一些,那么内存管理就是CPU内存资源的分配和回收,良好的内存管理机制在于尽量控制CPU内存资源的浪费。

Obj-C中语言中引用计数值的管理方式,对象每次alloc1次计数值为1同时获得内存,每retain 1次计数值加1,每release 1次计数值减1,直到计数值为0的时候,对象就会被销毁,主要的操控接口如下:

         Alloc、allocWithZone、new(并且初始化)——为对象分配内存,计数值+1,返回实例

         Release——计数值-1

         Retain——计数值+1

         Copy、mutableCopy——复制一个实例,计数值为1,返回实例,所得到的对象是一个全新的对象

         Autorelease在当前的上下文的autoreleasePool栈顶添加对象,由于它的引入使Obj-C的内存管理方式由全手动上升为半自动。

那么我们来看一段代码实例,演示下内存的计数值管理

[cpp] view plaincopy
  1. #import <Foundation/NSObject.h>  
  2. #import <Foundation/NSAutoreleasePool.h>  
  3. #import <Foundation/NSString.h>  
  4. #import <Foundation/NSArray.h>  
  5. #import <Foundation/NSValue.h>  
  6. Int main (int argc, char * argv[])  
  7. {  
  8.          NSAutoreleasePool* pool=[[NSAutoreleasePool alloc] init];  
  9.          NSNumber*myInt=[[NSNumber alloc] initWithInt: 100];//实例化一个NSNumber对象myInt,并且调用alloc方法,其引用计数值加1,为+1  
  10.          NSLog(@”myInt retain count=%lx”, (unsigned long) [myInt retainCount]);  
  11.          //输出myInt的引用计数  
  12.          [myInt retain];//myInt对象调用retain方法,引用计数值再+1,为+2  
  13.          NSLog(@”myInt retain count after retain=%lx”, (unsigned long) [myInt retainCount]);  
  14.          //输出myInt的引用计数  
  15.          [myInt release];//myInt对象调用release方法,引用计数值-1,为+1,此时myInt对象仍然存在,并未释放  
  16.          NSLog(@”myInt retain count after release=%lx”, (unsigned long) [myInt retainCount]);  
  17.          //输出myInt的引用计数值  
  18.          NSNumber* secant=[myInt copy];//myInt调用copy方法,返回引用计数为1的实例,此时secInt的引用计数值为1,myInt的引用计数值不变  
  19.          NSLog(@” secant retain count after copy=%lx”, (unsigned long) [secant retainCount]);  
  20.          [secInt release];//secInt调用release方法,引用计数-1,为0,secInt对象被彻底释放  
  21.          [myInt release];//myInt对象调用release方法,应用计数-1,为0,myInt对象被彻底释放  
  22.          [poold rain];  
  23.          return0;  
  24. }  


程序的最终输出结果如下:

myInt retain count=1

myInt retain count after retaine=2

myInt retain count after release=1

secInt retain count after copy=1

 

上述这段代码演示了计数机制是如何工作的,简单的规则就是,alloc和retain会让对象引用计数+1,release会让对象的引用计数-1,而copy对象则是只会将新的对象的引用计数+1,所以简单的规避内存泄露的一个方法就是有多少个alloc和retain,就要有多少个相应的release。

2.      对象释放池

有时候程序代码可能会返回临时变量,Obj-C提供了一种比较优雅的方式,就是延迟释放,即对象自动释放池。

[cpp] view plaincopy
  1. NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init];//声明对象以及对对象进行操作  
  2. [pool drain];//释放自动释放池  

当pool被建立以后,系统会自动生成一个数组,在当前上下文中有变量被置为autorelease的时候,系统就会把此变量加入数组当中,然后在[pool drain]时变量的内存计数值-1,因此设置为autorelease的变量不要手动释放,除非你retain过。

 

那么今天我们就是先简单的了解下Obj-C的内存管理,其实这个总的来说并不是特别复杂,但是它却是重中之重,起码在我看来,周围已经遇到好些个工程师因为内存泄露的问题导致程序产生比较严重的bug了,那么随着学习的不断深入,我们会对这块儿有更深入的了解和体会。

2013年4月18日,Eric.Tang 记

0 0