系統自動建立新的autorelease pool
在生成新的Run Loop的時候,系統會自動建立新的autorelease pool(非常感謝網友hhyytt和neogui的提醒)。注意,此處不同於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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
int main(int argc, char**argv) { NSLog(@"create an autorelasePool\n"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"create an instance of ClassA and autorelease\n"); ClassA *obj1 = [[[ClassA alloc] init] autorelease]; NSDate *now = [[NSDate alloc] init]; NSTimer *timer = [[NSTimer alloc] initWithFireDate:now interval:0.0 target:obj1 selector:@selector(createClassB) userInfo:nil repeats:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; [timer release]; [now release]; [runLoop run]; //在新loop中呼叫一函式,生成ClassB的autorelease例項 NSLog(@"releasing autorelasePool\n"); [pool release]; NSLog(@"autorelasePool is released\n"); return 0; } |
輸出如下:
1 2 3 4 5 6 7 |
create an autorelasePool create an instance of ClassA and autorelease create an instance of ClassB and autorelease ClassB destroyed releasing autorelasePool ClassA destroyed autorelasePool is released |
注意在我們銷燬autorelease pool之前,ClassB的autorelease例項就已經被銷燬了。
有人可能會說,這並不能說明新的run loop自動生成了一個新的autorelease pool,說不定還只是用了老的autorelease pool,只不過後來drain了一次而已。我們可以在main函式中不生成autorelease pool。精簡的示例程式碼如下,詳細程式碼請見附件中的memman-run-loop-without-pool.m。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
int main(int argc, char**argv) { NSLog(@"No autorelasePool created\n"); NSLog(@"create an instance of ClassA\n"); ClassA *obj1 = [[ClassA alloc] init]; NSDate *now = [[NSDate alloc] init]; NSTimer *timer = [[NSTimer alloc] initWithFireDate:now interval:0.0 target:obj1 selector:@selector(createClassB) userInfo:nil repeats:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; [timer release]; [now release]; [runLoop run]; //在新loop中呼叫一函式,生成ClassB的autorelease例項 NSLog(@"Manually release the instance of ClassA\n"); [obj1 release]; return 0; } |
輸出如下:
1 2 3 4 5 6 |
No autorelasePool created create an instance of ClassA create an instance of ClassB and autorelease ClassB destroyed Manually release the instance of ClassA ClassA destroyed |
我們可以看出來,我們並沒有建立任何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”];
示例程式碼檔案連結:http://files.cnblogs.com/VinceYuan/objective-c-memman.zip