标签:style blog http io ar color os 使用 sp
本篇博文,将给大家介绍下再Objective-C中如何使用内存管理。一个程序运行的时候,如果不及时的释放没有用的空间内存。那么,程序会越来越臃肿,内存占用量会不断升高。我们在使用的时候,就会感觉很卡,最终使得程序运行奔溃。因此,将无效的内存及时清理释放,是非常有必要的。
一个对象在最初创建使用,到最后的回收释放,经历的是怎样一个过程呢?
包括:诞生(通过alloc或new方法实现)、生存(接收消息并执行操作)、交友(通过复合以及向方法传递参数)、最终死去(被释放掉)。
一、引用计数
在对象创建的时候,Cocoa使用了一种叫引用计数的技术:
1)当一个对象被访问的时候,引用计数器的值就加1,可以给对象发送一条retain消息;
2)当结束该对象的访问的时候,引用计数器的值就减1,可以给对象发送一条release消息;
3)当引用计数器的值为0的时候,表示不再访问该对象,则其占用的系统内存将被回收重用,会自动给对象发送一条dealloc消息,一般都会重写dealloc方法;
4)要获得保留计数器当前的值,可以发送retainCount消息。
下面,介绍下几种方法的声明和实现方法:
首先,新建一个RetainTracker的类,修改类的声明文件和实现方法:
1 // RetainTracker.h 2 3 #import <Foundation/Foundation.h> 4 5 @interface RetainTracker : NSObject 6 -(id) retain; 7 -(oneway void)release; 8 -(NSUInteger)retainCount; 9 @end
1 // RetainTracker.m 2 3 #import "RetainTracker.h" 4 5 @implementation RetainTracker 6 -(id) init 7 { 8 if(self == [super init]) 9 { 10 NSLog(@"init: Retain count of %lu.", [self retainCount]); 11 } 12 return (self); 13 } 14 15 -(void) dealloc 16 { 17 NSLog(@"dealloc called. ByeBye!"); 18 [super dealloc]; 19 } 20 21 @end
然后在main.m主函数中调用retain,release,retainCount,dealloc等方法:
1 #import <Foundation/Foundation.h> 2 #import "RetainTracker.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 RetainTracker *tracker = [RetainTracker new];// count =1 7 8 [tracker retain]; 9 NSLog(@"retainCount: %lu", [tracker retainCount]);// count =2 10 11 [tracker retain]; 12 NSLog(@"retainCount: %lu", [tracker retainCount]);// count =3 13 14 [tracker release]; 15 NSLog(@"retainCount: %lu", [tracker retainCount]);// count =2 16 17 [tracker release]; 18 NSLog(@"retainCount: %lu", [tracker retainCount]);// count =1 19 20 [tracker retain]; 21 NSLog(@"retainCount: %lu", [tracker retainCount]);// count =2 22 23 [tracker release]; 24 NSLog(@"retainCount: %lu", [tracker retainCount]);// count =1 25 26 [tracker release];// count =0, dealloc 27 28 return (0); 29 }
运行结果如下:
二、自动释放
大家都知道,当对象不再使用的时候,要及时释放。但是在某些情况下,弄清楚什么时候不再使用一个对象并不容易。如果能够自动释放就好了。很幸运,Cocoa中有一个自动释放池(autorelease pool)。细心的朋友可以发现,在ios5以后,每次新建项目,在main函数中都有个@autoreleasepool方法,这就是将执行的代码都加到自动释放池中。
NSObject类提供了一个叫做autorelease的方法:
1 -(id) autorelease;
该方法预先设定一条会在未来某个时间发送的release消息。当给一个对象发送autorelease消息的时候,实际上是将该对象添加到自动释放池中。当自动释放池被销毁时,会向该池中的所有对象都发送release消息。
那么,接下来,我们就用添加到自动释放池的方法来修改上面的例子。RetainCount类的内容不改变,只要修改main主函数中的内容:
1 /* use auto release pool */ 2 int main(int argc, const char * argv[]) 3 { 4 NSAutoreleasePool *pool; 5 pool = [[NSAutoreleasePool alloc] init]; 6 7 RetainTracker *tracker = [RetainTracker new];// count =1 8 NSLog(@"after new, tracker: %lu", [tracker retainCount]);// count =1 9 10 [tracker retain]; 11 NSLog(@"after retain, tracker: %lu", [tracker retainCount]);// count =2 12 [tracker autorelease]; 13 NSLog(@"after autorelease, tracker: %lu", [tracker retainCount]);// count =2 14 15 [tracker release]; 16 NSLog(@"after release, tracker: %lu", [tracker retainCount]);// count =1 17 NSLog(@"releasing pool"); 18 [pool release]; // 销毁自动释放池 19 20 @autoreleasepool { 21 RetainTracker *tracker2; 22 tracker2 = [RetainTracker new]; // count = 1 23 [tracker2 retain]; //count =2 24 [tracker2 autorelease]; // count still = 2 25 [tracker2 release]; //count = 1 26 NSLog(@"auto releasing pool."); 27 } 28 29 return (0); 30 }
运行结果:
tracker对象,通过autorelease消息,将该对象添加到自动释放池中。当pool自动释放池发送release消息的时候,pool对象的引用计数器的值为0,则该自动释放池要被销毁,其dealloc方法被调用。使得自动释放池中的对象也都跟随其一起被销毁。
在下篇博文中,我们将继续介绍OC中内存管理的相关知识,介绍Cocoa的内存管理规则。
《objective-c基础教程》学习笔记(十)—— 内存管理之对象生命周期
标签:style blog http io ar color os 使用 sp
原文地址:http://www.cnblogs.com/jianglan/p/4154115.html