objc内存管理
http://blog.sina.com.cn/s/blog_538ee4a70100o9o2.html
如果要从事Leopard或更高版本的MacOS程序开发使用Objective-C 2.0的垃圾回收机制,若要从事旧版本MacOS或iPhone开发则要全部阅读本章内容
一、对象生命周期
程序中的对象由生命周期,其周期包括:诞生(alloc或new)、生存(接受消息和执行操作)、
1、引用计数
Cocoa采用了一种称为引用计数(保留计数)的技术:
(1)每个对象有一个与之相关联的整数,称为他的引用计数器或保留计数器
(2)当代码访问某个对象时,改代码将该对象保留计数器值增加1,表示我要访问该对象
(3)当代码结束对象访问时,将对象的保留计数器值减1,表示不再访问该对象
(4)在保留计数器值为0时,表示不再有代码访问该对象,对象将被销毁,启动垃圾回收机制
使用方法:
(1)使用alloc、new或通过copy消息(生成接收对象副本)创建对象时对象的保留计数器数值被设置为1
(2)要增加计数器值,可以调用对象的retain方法
-(id) retain; 返回一个id类型值。
通过这种方式,可以嵌套执行带有其他方法参数的保留调用,增加对象的保留计数器值并要求对象完成某种操作
例:[[car retain] setTire : tire anIndex : 2]
表示要求car对象将其保留计数器值加1并执行setTire操作
(3)要减少对象的保留计数器值,调用对象的release方法
-(void) release;
(4)当对象因保留计数器归0将被销毁时,Objective-C自动调用dealloc方法,此方法可重写,但不要直接调用,而是要让Objective-C自动调用
-(unsigned) retainCount;
(5)获得当前保留计数器的当前值,可以调用retainCount方法
2、对象所有权object ownership
如果一个对象具有指向其他对象的实际变量,则称该对象拥有这些对象
3、访问方法中对象的保留和释放
-(void) setEngine : (Engine *) newEngine
{
}
二、自动释放
1、所有对象全部入池
Cocoa中有一个自动释放池(autorelease
NSObject类提供了一个autorelease方法:-(id) autorelease;
该方法预先设定了一条在将来某个时间发送的release方法,其返回值是接收消息的对象
当给一个对象发送autorelease方法时,实际上是将该对象添加到NSAutoreleasePool中,自动释放池被销毁时,回想该池中的所有对象发送release消息
举例代码:
description方法首先创建了一个新的字符串对象,然后自动释放,最后将其返回给调用的函数
2、自动释放池的销毁时间
Cocoa定期自动创建和销毁自动释放池,通常是在处理完当前事件以后执行操作。
我们可以使用任意多的自动释放对象,当不需要他们时,自动释放池将自动为你清理这些对象
NSAutoreleasePool
pool = [[NSAutoreleasePool alloc] init];
……
[pool release];
Tip:Xcode自动生成的另一种销毁自动释放池-drain方法只是清空自动释放池而不销毁它,这种方法只适用于10.4以及更高版本,使用-release方法适用于全部版本
3、自动释放池的工作过程
举例代码:
三、Cocaoa内存管理规则
规则:
(1)
(2)
(3)
1、临时对象
使用任何其他方法(非new、alloc或者copy)获得对象不需要关心如何销毁该对象
举例代码:
arrayWithCapacity不属于alloc、new、copy方法,使用该方法返回的对象保留计数器值为1并且已经被设置为自动施放
举例代码:
blueColor返回一个全局单例对象,这个对象永远不会被销毁
2、拥有对象
(1)使用new、alloc或copy方法获得对象,手动释放
举例代码:
(2)使用非new、alloc或copy方法获得对象,自动释放
(3)再循环中清空自动释放池
举例代码:
3、垃圾回收
Objective-C 2.0引入了自动内存管理机制,也称垃圾回收
启动垃圾回收功能:转到项目信息窗口的Build选项卡,然后选择Required [-fobjc-gc-only]选项即可
Tip: -fobjc-gc是为了使代码既支持垃圾回收又支持对象的保留和释放
启用垃圾回收以后,内存管理命令全部变成了空操作指令,不执行任何操作