我通过在一个简单的命令行程序中使用一些代码来学习Objective-C,这是我的代码:
#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等对象并针对Foundation编译的命令行应用程序需要手动创建自动释放池吗?我的榜样是最好的做法吗?
注意:我也试过[你好发布];没有NSAutoreleasePool,看看我是否可以在不使用池的情况下手动清理内存,但是遇到了同样的问题。
答案 0 :(得分:9)
是的,是的。
Cocoa(以GUI或Foundation形式)期望存在自动释放池;框架的内部(不仅仅是你自己的代码)自由地使用-autorelease
消息和池,如果你在自动释放池堆栈上没有任何池,它会抱怨,并泄漏对象,正如你所见。
我认为你关闭了垃圾收集;我从未开发过它,但在那种情况下,我可以想象你不需要它。
更新现在可以使用具有相同效果的@autoreleasepool {...}
块创建自动释放池,以及一些不错的奖励,例如能够跳出/退出它。