stringWithContentsOfURL泄漏内存

时间:2009-08-30 18:51:41

标签: iphone objective-c memory-leaks autorelease

如果我告诉fetchHTML是在一个单独的线程中调用的话会不会有更多的亮点呢?我还在调试控制台中看到了几条消息,例如:

_NSAutoreleaseNoPool():类NSCFDictionary的对象0xd92860自动释放,没有池到位 - 只是泄漏

_NSAutoreleaseNoPool():类NSCFString的对象0xd92800自动释放,没有池到位 - 只是泄漏

我是iPhone应用程序开发的新手,Objective-C但不是编程或C / C ++的新手。我正在使用泄漏性能工具,它显示了许多泄漏。这是一个10.5 kb的泄漏,它发生在这一行:

NSString * xml = [NSString stringWithContentsOfURL:urlobj];

下面的堆栈跟踪是:

stringWithContentsOfURL
initWithContentsOfURL
initWithDataOfEncoding
...

有没有人知道为什么必须这样做。我的印象是我在这里获得了一个autorelease对象,我可以在不调用retain的情况下将其返回给调用者。我没有使用xml对象存储在实例变量中,仅用于处理。

这是功能代码:

- (NSString *) fetchHTML: (NSString* ) url{
    @try
    {
        NSURL* urlobj = [NSURL URLWithString:url];
        NSString * xml = [NSString stringWithContentsOfURL:urlobj];
        return xml;
    }
    @catch( NSException *ex){
        NSLog(@"Error fetchingHTML");
        return nil;
    }
    return nil;
}

3 个答案:

答案 0 :(得分:1)

烨;那不应该泄漏。

这可能是一个误报,因为URL子系统正在缓存URL的内容,并且这样做的方式是指针不再可见于泄漏分析。

如果可以,请在Snow Leopard上重试测试。 Snow Leopard上的泄漏检测速度更快,更准确。

答案 1 :(得分:1)

我完全同意你的意见,这不应该导致泄密。我已经在Cocoa / Objective-C编写了2年的编码,看起来它应该可行。

话虽如此,我注意到Apple的文档表明stringWithContentsOfURL:方法正在deprecated。也许它会起作用如下:

NSString * xml = [[NSString alloc]
                  initWithContentsOfURL:urlobj
                               encoding:NSASCIIStringEncoding
                                  error:nil];
return [xml autorelease];

答案 2 :(得分:1)

正如错误消息所示,字符串没有自动释放池,这会产生泄漏。 NSAutoreleasePools基于每个线程存在。 Cocoa在主线程的主事件循环中创建一个,但这是它为您创建的唯一一个。如果你在主线程之外的某个地方并且你将要处理自动释放的对象,你还需要为该线程创建一个自动释放池。

您可以查看NSAutoreleasePool docs以获取有关自动释放池堆栈如何工作的更多信息。