代码之家  ›  专栏  ›  技术社区  ›  Jesse Beder

使用xcode为iPhone编译时出现内存泄漏日志消息

  •  1
  • Jesse Beder  · 技术社区  · 15 年前

    当我编译iPhone项目时(在命令行中),日志输出如下:

    2009-11-05 22:19:57.494 xcodebuild[51128:613] warning: compiler 'com.apple.compilers.llvm.clang.1_0.analyzer' is based on missing compiler 'com.apple.compilers.llvm.clang.1_0.analyzer'
    === BUILDING NATIVE TARGET Foo OF PROJECT foo WITH THE DEFAULT CONFIGURATION (AdHoc) ===
    
    Checking Dependencies...
    2009-11-05 22:19:58.032 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x722d410 of class NSCFString autoreleased with no pool in place - just leaking
    Stack: (0x97257f4f 0x97164432 0xfea624 0x2620e34 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012)
    2009-11-05 22:19:58.035 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x720b370 of class NSCFDictionary autoreleased with no pool in place - just leaking
    Stack: (0x97257f4f 0x97164432 0x2621454 0x262012a 0x2620e53 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012)
    2009-11-05 22:19:58.038 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x720b370 of class NSCFDictionary autoreleased with no pool in place - just leaking
    Stack: (0x97257f4f 0x97164432 0x2621454 0x2620174 0x2620e53 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012)
    2009-11-05 22:19:58.044 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x7111690 of class NSCFDictionary autoreleased with no pool in place - just leaking
    Stack: (0x97257f4f 0x97164432 0x2611215 0x2620f50 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012)
    2009-11-05 22:19:58.078 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x7114c10 of class NSCFNumber autoreleased with no pool in place - just leaking
    Stack: (0x97257f4f 0x97164432 0x2611242 0x2620f50 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012)
    2009-11-05 22:19:58.088 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x71a28c0 of class NSCFNumber autoreleased with no pool in place - just leaking
    Stack: (0x97257f4f 0x97164432 0x2611286 0x2620f50 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012)
    

    然后有一大堆处理命令(一堆 setenv s),然后 CompileC 命令开始执行,其中一些(但不是全部,可能有10%)随后会有更多关于泄漏的投诉。

    但是,它编译正确,运行良好。我用泄漏运行它,它发现了两个16字节的泄漏,我还不能完全追踪到,但没有按照上面混乱的消息的顺序。另外,它怎么知道有泄漏 编译 是吗?

    3 回复  |  直到 15 年前
        1
  •  6
  •   James Wald    15 年前

    简而言之,编译器比您想象的要聪明;)。这些错误意味着您在没有分配NSAutoReleasePool的上下文中自动释放各种对象(NSString、NSDictionary、NSNumber)。例如,项目的主.m文件应该声明一个自动释放池:

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

    在许多应用程序中,这将是唯一分配的池。没有这个池,你就不能自动释放任何东西,如果你试图自动释放,它没有池去,所以它实际上成为一个泄漏。检查您的主要功能,确保分配了NSAutoReleasePool。

    在其他情况下,您可能希望声明另一个NSAutoReleasePool。最常见的情况是在新线程中调用选择器。每个线程都必须有自己的nsAutoReleasePool。有关详细信息,请参阅第36张幻灯片 Stanford University CS193P 第10讲:

    - (void)someAction:(id)sender {
        // Fire up a new thread
        [NSThread detachNewThreadSelector:@selector(doWork:) withTarget:self object:someData];
    }
    
    - (void)doWork:(id)someData {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [someData doLotsOfWork];
    
        // Message back to the main thread
        [self performSelectorOnMainThread:@selector(allDone:) withObject:[someData result] waitUntilDone:NO];
        [pool release];
    }
    

    另一个例子是一个昂贵的循环,其中您正在自动释放许多对象。与其让主要的nsautoreleasepool增长到一个巨大的规模,你会发现在循环中每隔n次创建一个新的nsautoreleasepool将有助于将资源使用保持在最低水平。其中一些代码还借用了上面列出的演讲幻灯片:

    int N = 10;
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    for (int i = 0; i < someLargeNumber; i++) {
        NSString *string = ...;
        string = [string lowercaseString];
        string = [string stringByAppendingString:...];
        NSLog(@“%@”, string);
    
        // Release the temporary pool and allocate a new one
        // every N times around the loop
    
        if (i % N == 0) {
            [pool release];
            pool = [[NSAutoreleasePool alloc] init];
        }
    }
    
    [pool release];
    

    也许您有一些这样的代码,它们并不总是按预期分配或释放池。不过,我不确定编译器是否足够聪明,无法注意到这种类型的问题。

        2
  •  1
  •   Donovan Voss    15 年前

    这些警告可能是因为工具本身存在泄漏。但是,如果没有设置自动释放池,那么这些类型的消息就是您在线程中运行或在后台执行选择器时看到的。

        3
  •  0
  •   nacho4d    15 年前

    即使有漏洞,大多数程序也能正常运行,…但不管怎样,我认为你没有显示足够的信息。 我猜你发送的是一个对象自动释放在没有池的地方?洛尔 你试过乐器吗?

    推荐文章