3

在我的 iPhone 应用程序中,在调用任何代码之前,我在应用程序一开始就在控制台中收到了三个奇怪的警告:

*** __NSAutoreleaseNoPool(): Object 0x84be00 of class NSCFString autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x84b000 of class NSCFString autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x849c00 of class NSCFString autoreleased with no pool in place - just leaking

我在许多地方使用 MBProgressHUD 来显示进度指示器,这是关于此问题的其他一些讨论所指出的,因为它在显示进度指示器时会引发一个新线程。但最奇怪的是,这些似乎甚至在我的 main() 函数开始之前就被抛出了:

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

当我在我的代码中的第一个断点时NSAutoreleasePool,甚至在该行运行之前,我都会收到此警告。假设在此之前我没有运行任何我自己的代码,可能导致错误的原因是什么?

4

5 回答 5

5

main()在触发此问题之前,您可能有一个正在运行的构造函数。您正在链接哪些库和/或正在使用任何__attribute__指令?


疱疹。

意识到了一些显而易见的事情。由于对象被泄露,它们仍然存在。设置断点main(),然后在 GDB 提示符下键入po 0x84be00(仅替换0x84be00为泄露的字符串之一的地址)。

这将向您显示该字符串的内容,并为您提供关于原因的非常好的线索。

德普。

设置断点__NSAutoreleaseNoPool并查看回溯向您显示的内容。

我今天显然失败了(只是因为我已经走这条路 1827.314 万次)。

于 2011-03-21T02:14:49.337 回答
2

我一直在寻找这个问题的答案,但经过一番研究,我设法弄清楚了问题所在。我也有这个错误发生在 main 执行之前,我通过实现一个名为 + (void)load 的方法来跟踪它,我认为这是一个加载一些全局类特定数据的好名字。我没有意识到实际上已经定义了负载并且我使用它覆盖了默认负载,并且负载在 main 之前执行。因此,我正在泄漏。将其重命名为 myload 修复了它。

于 2012-02-03T13:19:36.023 回答
2

您在应用程序的某处有一个静态变量,该变量正在主运行循环之外进行初始化。就像是:

static UIImage *myImage = [UIImage imageNamed:@"fred.png"];

寻找任何初始化对象的静态变量,并在 applicationDidFinishLaunching 之类的东西中初始化它们,以使用适当的自动释放池来设置它们。

即使它说 NSString 正在泄漏,它也可能是任何类型的对象。

于 2011-03-21T03:19:52.197 回答
2

在使用后台线程的应用程序中,您需要在后台方法中创建一个自动释放池:

-(void)myMethodThatRunsOnBackground:(id)param {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  //body of method

  [pool release];
}

答案信用:iphonedevsdk.com 上的 nobre84

于 2011-08-26T14:57:32.907 回答
0

您可以尝试为 autorelease 放置一个符号断点,以查看调用它的位置和时间。

于 2011-03-21T02:02:37.463 回答