【问题标题】:"Object 0x84be00 of class NSCFString autoreleased with no pool in place - just leaking" - but on the first line of the app!“NSCFString 类的对象 0x84be00 自动释放,没有适当的池 - 只是泄漏” - 但在应用程序的第一行!
【发布时间】:2011-07-19 09:21:19
【问题描述】:

在我的 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 的代码中放置断点时,甚至在该行运行之前,我都会收到此警告。假设在此之前我没有运行任何自己的代码,可能导致错误的原因是什么?

【问题讨论】:

    标签: iphone objective-c ios memory-management nsautoreleasepool


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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


      疱疹。

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

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

      呸。

      __NSAutoreleaseNoPool 上设置断点,看看回溯会显示什么。

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

      【讨论】:

      • 我正在链接许多库和基础类,包括:libxml2.dylib、Foundation.framework、UIKit.framework、CoreGraphics.framework、CoreData.framework、libcucore.A.dylib、QuartzCore。框架、SystemConfiguration.framework、Security.framework、MessageUI.framework、CFNetwork.framework、AddressBook.framework、AddressBookUI.framework、AudioToolbox.framework、libteEngine.a(这是用于TextExpander Touch支持)和libxml2.2.7.3.dylib .如何检查我正在使用的 __attribute__ 指令?
      • 如果你不知道,你可能没有使用任何(它们不常见)。问题不会来自系统框架(可能只是可能在模拟器中)。
      • 另外,我如何在 __NSAutoreleaseNoPool 上设置断点,因为它实际上不在我自己的代码中?
      • 在 gdb 提示符下,b __NSAutoreleaseNoPool 可以工作。或者您可以使用断点检查器并创建一个符号断点。
      【解决方案3】:

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

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

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

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

      【讨论】:

      • 我的代码中有许多 static 变量,一些在外部库中。有没有一种方法可以测试哪个是罪魁祸首,而无需简单地逐个注释掉它们?
      • 最快的方法可能是注释掉并运行——一次做几个,然后对罪魁祸首进行二进制搜索。 _NSNoAutoReleasePool 也可以工作(虽然我有时会跳过该断点)。
      【解决方案4】:

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

      -(void)myMethodThatRunsOnBackground:(id)param {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
      
        //body of method
      
        [pool release];
      }
      

      答案:nobre84 on iphonedevsdk.com

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • 这是我同样的问题。有一个 +load 方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多