Objective-C内存管理

系统自动创建新的autorelease pool

在生成新的Run Loop的时候,系统会自动创建新的autorelease pool。注意,此处不同于xcode在新建项目时自动生成的代码中加入的autorelease pool,xcode生成的代码可以被删除,但系统自动创建的新的autorelease pool是无法删除的(对于无Garbage Collection的环境来说)。Objective-C没有给出实现代码,官方文档也没有说明,但我们可以通过小程序来证明。

在这个小程序中,我们先生成了一个autorelease pool,然后生成一个autorelease的ClassA的实例,再在一个新的run loop中生成一个autorelease的ClassB的对象(注意,我们并没有手动在新run loop中生成autorelease pool)。精简的示例代码如下,详细代码请见附件中的memman-run-loop-with-pool.m。

intmain(intargc,char**argv)

{

NSLog(@"create an autorelasePool\n");

NSAutoreleasePool *pool=[[NSAutoreleasePoolalloc]init];

NSLog(@"create an instance of ClassA and autorelease\n");

ClassA *obj1=[[[ClassAalloc]init]autorelease];

NSDate *now=[[NSDatealloc]init];

NSTimer *timer=[[NSTimeralloc]initWithFireDate:now

interval:0.0

target:obj1

selector:@selector(createClassB)

userInfo:nil

repeats:NO];

NSRunLoop *runLoop=[NSRunLoopcurrentRunLoop];

[runLoopaddTimer:timerforMode:NSDefaultRunLoopMode];

[timerrelease];

[nowrelease];

[runLooprun];//在新loop中调用一函数,生成ClassB的autorelease实例

NSLog(@"releasing autorelasePool\n");

[poolrelease];

NSLog(@"autorelasePool is released\n");

return0;

}

输出如下:

createanautorelasePool

createaninstanceofClassAandautorelease

createaninstanceofClassBandautorelease

ClassBdestroyed

releasingautorelasePool

ClassAdestroyed

autorelasePoolisreleased

注意在我们销毁autorelease pool之前,ClassB的autorelease实例就已经被销毁了。

有人可能会说,这并不能说明新的run loop自动生成了一个新的autorelease pool,说不定还只是用了老的autorelease pool,只不过后来drain了一次而已。我们可以在main函数中不生成autorelease pool。精简的示例代码如下,详细代码请见附件中的memman-run-loop-without-pool.m。

intmain(intargc,char**argv)

{

NSLog(@"No autorelasePool created\n");

NSLog(@"create an instance of ClassA\n");

ClassA *obj1=[[ClassAalloc]init];

NSDate *now=[[NSDatealloc]init];

NSTimer *timer=[[NSTimeralloc]initWithFireDate:now

interval:0.0

target:obj1

selector:@selector(createClassB)

userInfo:nil

repeats:NO];

NSRunLoop *runLoop=[NSRunLoopcurrentRunLoop];

[runLoopaddTimer:timerforMode:NSDefaultRunLoopMode];

[timerrelease];

[nowrelease];

[runLooprun];//在新loop中调用一函数,生成ClassB的autorelease实例

NSLog(@"Manually release the instance of ClassA\n");

[obj1release];

return0;

}

输出如下:

NoautorelasePoolcreated

createaninstanceofClassA

createaninstanceofClassBandautorelease

ClassBdestroyed

ManuallyreleasetheinstanceofClassA

ClassAdestroyed

我们可以看出来,我们并没有创建任何autorelease pool,可是ClassB的实例依然被自动销毁了,这说明新的run loop自动创建了一个autorelease pool,这个pool在新的run loop结束的时候会销毁自己(并自动release所包含的对象)。

补充说明

在研究retain count的时候,我不建议用NSString。因为在下面的语句中,

NSString *str1 = @”constant string”;

str1的retain count是个很大的数字。Objective-C对常量字符串做了特殊处理。

当然,如果你这样创建NSString,得到的retain count依然为1

NSString *str2 = [NSString stringWithFormat:@”123”];

你可能感兴趣的:(Objective-C内存管理)