2011-06-08 46 views
8

我用一個簡單的命令行程序的一些代碼玩耍學習Objective-C,這裏是我的代碼:Objective-C命令行程序是否需要NSAutoreleasePool?

#import <Foundation/Foundation.h> 
#import <stdio.h> 

int main(int argc, char** argv) 
{ 
    NSString *hello = @"hello world"; 

    printf("msg: %s\n", [hello UTF8String]); 

    return 0; 
} 

我編譯,這樣運行:

gcc test.m -o test -ObjC -framework Foundation 
./test 

,並得到下面的輸出:

2011-06-08 20:35:21.178 test[10220:903] *** __NSAutoreleaseNoPool(): Object 
0x10010c8b0 of class NSCFData autoreleased with no pool in place - just leaking 
msg: hello world 

所以我可以看到,錯誤指的是一個事實,即沒有NSAutoreleasePool,當我加一個,錯誤消失:

#import <Foundation/Foundation.h> 
#import <stdio.h> 

int main(int argc, char** argv) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSString *hello = @"hello world"; 

    printf("msg: %s\n", [hello UTF8String]); 

    [pool release]; 

    return 0; 
} 

所以我正確地認爲使用像NSString等對象和編譯對基礎的命令行應用程序需要自動發佈池手動創建?我的榜樣是最好的做法嗎?

注:我也試過[hello release];沒有NSAutoreleasePool來查看我是否可以在不使用池的情況下手動清除內存,但遇到同樣的問題。

回答

9

是的,是的。

可可(以GUI或基礎形式)期望自動釋放池出現;框架的內部(不僅僅是你自己的代碼)會自由地使用-autorelease消息和池,如果你在autorelease池棧中沒有任何池,它會發出抱怨,並泄漏對象,就像你'已經看到。

我認爲你已關閉垃圾回收功能;我從來沒有開發過,但在這種情況下,我可以想象你不需要這個。

更新自動釋放池現在可以使用@autoreleasepool {...}塊,它具有相同的效果,一些不錯的獎金喜歡自己跳/回了它的能力產生。

+0

謝謝,清楚的解釋,並確認我在正確的線:) – Martin 2011-06-08 19:55:33

+1

如果你知道你永遠不會調用autoreleased方法(例如,你總是明確'alloc','init'和'釋放「你的對象),但這是非常罕見的,並且幾乎只發生在從未調用任何庫函數的玩具程序中。 – 2011-06-08 20:35:13