首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

Objective-C语法以内存管理

2013-07-01 
Objective-C语法之内存管理1、Objective-C内存管理简介:? ? Objective-C需要自己考虑内存的管理,对于从Java

Objective-C语法之内存管理

1、Objective-C内存管理简介:

? ? Objective-C需要自己考虑内存的管理,对于从Java, C#等语言转向Objective-C平台的程序员新手来说,这是个很大的挑战。幸运的是,如果熟悉了Objective-C的内存管理机制,手工管理内存也没有那么可怕。?Objective-C的内存管理介于C/C++和Java C#直接,不像C/C++语言内存管理全部需要程序员一手包办,也不像Java C#语言有那么完备的内存垃圾回收器。(Objective-C 2.0有GC机制,不过不支持IOS)。那他是怎么管理内存的呢?通过引用计数进行管理的。PS:在iOS 5后增加了Automatic Reference Counting(ARC 自动引用计数)特性,这样程序员不需要自己操心管理内存了,ARC和GC不一样,ARC是编译器的行为。ARC后面再讲。不过熟悉Objective-C的内存管理机制是非常必要的。

2、内存管理原理:

? ?Objective-C内存管理模型是基于对象的所有权。如果你拥有这个对象,那么你就有责任去释放它。一个对象可以有多个拥有者。如果这个对象的拥有和为0时,系统将自动释放这个对象。对象的所有权和释放有四个原则:

?

    任何你创建的对象你都获得其所有权。(包括 alloc ,new ,copy等关键字获得的对象)通过retain获得对象的所有权如果你不需要一个对象了,你必须释放所有权你不能释放你没有所有权的对象引用计数(retainCount)是Objective-C对象引用的唯一依据。调用实例管理的release方法后,此属性减1,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。Objective-C语法以内存管理图片来自苹果官网。

    3、示例:环境是在不选择ARC的环境下新建Person类,使他继承与NSObject,在.m文件中实现dealloc方法:[cpp]?view plaincopy
    1. -?(void)?dealloc????
    2. {????
    3. ????NSLog?(@"dealloc?called.?Bye?Bye.");????
    4. ????[super?dealloc];????
    5. ??????
    6. }???
    在引用计数为0时,这个方法就会被调用,证明这个对象被销毁。?创建一个对象,打印它的引用计数[cpp]?view plaincopy
    1. Person?*person?=?[[Person?alloc]?init];??
    2. ??
    3. NSLog(@"对象person的retainCount:?%d",?[person?retainCount]);??

    [cpp]?view plaincopy

    1. Person?*person?=?[[Person?alloc]?init];??
    2. ?NSLog(@"对象person的retainCount:?%d",[person?retainCount]?);??
    3. ?[person?retain];??
    4. ?NSLog(@"对象person的retainCount:?%d",?[person?retainCount]);??

    ?

    打印结果:

    [cpp]?view plaincopy

    1. Person?*person?=?[[Person?alloc]?init];??
    2. NSLog(@"对象person的retainCount:?%d",[person?retainCount]?);??
    3. [person?retain];??
    4. NSLog(@"对象person的retainCount:?%d",?[person?retainCount]);??
    5. [person?release];??
    6. [person?release];??
    7. NSLog(@"对象person的retainCount:?%d",?[person?retainCount]);??

    这个代码最后打印出来的retainCount是0吗?打印结果:

    [cpp]?view plaincopy
    1. 2012-07-05?16:05:29.830?ObjectiveCTest[2847:f803]?对象person的retainCount:?1??
    2. 2012-07-05?16:05:29.831?ObjectiveCTest[2847:f803]?对象person的retainCount:?2??
    3. 2012-07-05?16:05:29.831?ObjectiveCTest[2847:f803]?dealloc?called.?Bye?Bye.??
    4. 2012-07-05?16:05:29.832?ObjectiveCTest[2847:f803]?对象person的retainCount:?1??

    震惊了,第一次release 时retainCount减1了,再release , d对象的dealloc called了,但是retainCount 还是1.在stackoverflow.com的查了一下,有人说这个retainCount没什么用。。。。可以事实的确如retainCount是1,对象被干掉了。有人说,要把person = nil。这样retainCount就是0了。试了下,nil的 retainlCount永远是0.这个赋值没有意义。

    4、NSAutoreleasePool自动释放内存

    如果仅仅是创建,释放,这样对应,就很好理解。但是大多数人不理解的是自动释放内存这个地方,感觉琢磨不透,但其实原理也很简单。
    C/C++编程时有个很重要的对内存管理的原则:谁创建谁销毁。但是这个原则在有些情况下却无法遵守:比如让一个普通函数返回一块内存区域。函数调用者必须在函数调用完毕后自己负责销毁这块内存,而在Objective-C的自动内存释放的机制下,就不用那么烦恼了。

    先看看最经典的程序入口程序,也用到自动释放。

    [cpp]?view plaincopy
    1. NSAutoreleasePool?*pool?=?[[NSAutoreleasePool?alloc]?init];??
    2. int?retVal?=?UIApplicationMain(argc,?argv,?nil,?nil);??
    3. [pool?release];??

    我们先把pool看成一个普通对象,先是alloc,pool的retainCount为1。
    第三句release,retainCount为0,自动调用它的dealloc方法。它和任何其它普通对象没 任何区别。
    神奇的地方在哪里?
    NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,

    ?

    ?

    [cpp]?view plaincopy
    1. NSAutoreleasePool?*pool?=?[[NSAutoreleasePool?alloc]?init];??
    2. Person?*person?=?[[Person?alloc]?init];??
    3. NSLog(@"对象person的retainCount:?%d",[person?retainCount]?);??
    4. [person?autorelease];??
    5. NSLog(@"到这里,person还没被释放");??
    6. [pool?release];??

    ?

    打印结果:

    ?

    [cpp]?view plaincopy
    1. 2012-07-05?16:34:38.823?ObjectiveCTest[3045:f803]?对象person的retainCount:?1??
    2. 2012-07-05?16:34:38.823?ObjectiveCTest[3045:f803]?到这里,person还没被释放??
    3. 2012-07-05?16:34:38.824?ObjectiveCTest[3045:f803]?dealloc?called.?Bye?Bye.??

    在调用pool release的时候,person才被释放。这就是自动释放的神奇的地方,这样就可以创建对象

    著作权声明:本文由http://blog.csdn.net/totogo2010/原创

热点排行