系统自动创建新的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”];