stringWithContentsOfURL 泄漏内存

发布于 2024-08-03 07:16:33 字数 1064 浏览 6 评论 0原文

如果我告诉 fetchHTML 是在单独的线程中调用的,是否会更清楚?我还在调试控制台中看到几条消息,例如:

_NSAutoreleaseNoPool(): Object 0xd92860 of class NSCFDictionary autoreleased with no pool in place - just Leaking

_NSAutoreleaseNoPool(): Object 0xd92800 of class NSCFString autoreleased with no pool in place - just Leaking

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

NSString * xml = [NSString stringWithContentsOfURL:urlobj];

下面的堆栈跟踪是:

stringWithContentsOfURL
initWithContentsOfURL
initWithDataOfEncoding
...

有谁知道为什么会发生这种情况。我的印象是,我在这里得到了一个自动释放对象,我可以将其返回给调用者,而无需调用保留。我没有使用 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;
}

Would it shed more light if I told that fetchHTML was being called in a seperate thread? I am also seeing several messages in the debug console such as:

_NSAutoreleaseNoPool(): Object 0xd92860 of class NSCFDictionary autoreleased with no pool in place - just leaking

_NSAutoreleaseNoPool(): Object 0xd92800 of class NSCFString autoreleased with no pool in place - just leaking

I am new to iPhone app development, Objective-C but not new to programming or C/C++. I am using the leaks performance tool and it shows many leaks. This is a 10.5 kb leak and it occurs on the line:

NSString * xml = [NSString stringWithContentsOfURL:urlobj];

The stack trace on this below is:

stringWithContentsOfURL
initWithContentsOfURL
initWithDataOfEncoding
...

Does anyone have an idea why this must be happening. I am under the impression that I get an autorelease object here and I can return this to the caller without calling retain. I am not using the xml object to store in an instance variable, just for processing.

Here is the function code:

- (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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

国际总奸 2024-08-10 07:16:33

是的;那不应该泄漏。

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

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

Yup; that shouldn't be leaking.

It might be a false positive in that the URL subsystem is caching the contents of the URL and doing so in a way where the pointer is no longer visible to leaks analysis.

If you can, retry the test on Snow Leopard. Leaks detection on Snow Leopard is significantly faster and more accurate.

乖乖兔^ω^ 2024-08-10 07:16:33

我完全同意你的观点,这不应该导致泄漏。我已经用 Cocoa/Objective-C 编码两年了,看起来它应该可以工作。

话虽这么说,我注意到苹果的文档表明 stringWithContentsOfURL: 方法正在 已弃用。也许它会按如下方式工作:

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

I completely agree with you that this should not cause a leak. I've been coding in Cocoa/Objective-C for 2 years now, and that looks like it should work.

That being said, I notice that Apple's documentation indicates that the stringWithContentsOfURL: method is being deprecated. Perhaps it would work as follows:

NSString * xml = [[NSString alloc]
                  initWithContentsOfURL:urlobj
                               encoding:NSASCIIStringEncoding
                                  error:nil];
return [xml autorelease];
征棹 2024-08-10 07:16:33

正如错误消息所示,没有可供字符串进入的自动释放池,这会造成泄漏。 NSAutoreleasePools 以每个线程为基础存在。 Cocoa 在主线程的主事件循环中创建一个,但这是它为您创建的唯一一个。如果您位于主线程以外的某个位置并且要处理自动释放对象,则还需要为该线程创建一个自动释放池。

您可以查看 NSAutoreleasePool 文档 了解有关自动释放池堆栈如何工作的更多信息。

As the error message says, there's no autorelease pool for the string to go into, and that creates a leak. NSAutoreleasePools exist on a per-thread basis. Cocoa creates one in the main event loop of the main thread, but that's the only one it creates for you. If you're somewhere other than the main thread and you're going to be dealing with autoreleased objects, you need to create an autorelease pool for that thread as well.

You can check out the NSAutoreleasePool docs for more information on how autorelease pool stacks work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文