系統(tǒng)自動(dòng)創(chuàng)建新的autorelease pool
在生成新的Run Loop的時(shí)候,系統(tǒng)會(huì)自動(dòng)創(chuàng)建新的autorelease pool卖擅。注意,此處不同于xcode在新建項(xiàng)目時(shí)自動(dòng)生成的代碼中加入的autorelease pool,xcode生成的代碼可以被刪除惩阶,但系統(tǒng)自動(dòng)創(chuàng)建的新的autorelease pool是無(wú)法刪除的(對(duì)于無(wú)Garbage Collection的環(huán)境來(lái)說(shuō))挎狸。Objective-C沒(méi)有給出實(shí)現(xiàn)代碼,官方文檔也沒(méi)有說(shuō)明断楷,但我們可以通過(guò)小程序來(lái)證明锨匆。
在這個(gè)小程序中,我們先生成了一個(gè)autorelease pool冬筒,然后生成一個(gè)autorelease的ClassA的實(shí)例恐锣,再在一個(gè)新的run loop中生成一個(gè)autorelease的ClassB的對(duì)象(注意,我們并沒(méi)有手動(dòng)在新run loop中生成autorelease pool)舞痰。精簡(jiǎn)的示例代碼如下土榴,詳細(xì)代碼請(qǐng)見(jiàn)附件中的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中調(diào)用一函數(shù)响牛,生成ClassB的autorelease實(shí)例
NSLog(@"releasing autorelasePool\n");
[poolrelease];
NSLog(@"autorelasePool is released\n");
return0;
}
輸出如下:
createanautorelasePool
createaninstanceofClassAandautorelease
createaninstanceofClassBandautorelease
ClassBdestroyed
releasingautorelasePool
ClassAdestroyed
autorelasePoolisreleased
注意在我們銷(xiāo)毀autorelease pool之前玷禽,ClassB的autorelease實(shí)例就已經(jīng)被銷(xiāo)毀了。
有人可能會(huì)說(shuō)呀打,這并不能說(shuō)明新的run loop自動(dòng)生成了一個(gè)新的autorelease pool矢赁,說(shuō)不定還只是用了老的autorelease pool,只不過(guò)后來(lái)drain了一次而已贬丛。我們可以在main函數(shù)中不生成autorelease pool撩银。精簡(jiǎn)的示例代碼如下,詳細(xì)代碼請(qǐng)見(jiàn)附件中的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中調(diào)用一函數(shù)额获,生成ClassB的autorelease實(shí)例
NSLog(@"Manually release the instance of ClassA\n");
[obj1release];
return0;
}
輸出如下:
NoautorelasePoolcreated
createaninstanceofClassA
createaninstanceofClassBandautorelease
ClassBdestroyed
ManuallyreleasetheinstanceofClassA
ClassAdestroyed
我們可以看出來(lái),我們并沒(méi)有創(chuàng)建任何autorelease pool焕阿,可是ClassB的實(shí)例依然被自動(dòng)銷(xiāo)毀了咪啡,這說(shuō)明新的run loop自動(dòng)創(chuàng)建了一個(gè)autorelease pool,這個(gè)pool在新的run loop結(jié)束的時(shí)候會(huì)銷(xiāo)毀自己(并自動(dòng)release所包含的對(duì)象)暮屡。
補(bǔ)充說(shuō)明
在研究retain count的時(shí)候撤摸,我不建議用NSString。因?yàn)樵谙旅娴恼Z(yǔ)句中褒纲,
NSString *str1 = @”constant string”;
str1的retain count是個(gè)很大的數(shù)字准夷。Objective-C對(duì)常量字符串做了特殊處理。
當(dāng)然莺掠,如果你這樣創(chuàng)建NSString衫嵌,得到的retain count依然為1
NSString *str2 = [NSString stringWithFormat:@”123”];