【问题标题】:Can't find the leak in this Objective-C NSXMLParser code?在这个 Objective-C NSXMLParser 代码中找不到漏洞?
【发布时间】:2010-02-19 17:49:43
【问题描述】:

我是 iPhone 编程的新手,我正在针对 Instruments 中的 Leaks 工具运行我的应用程序。该工具发现了一些泄漏,所有这些似乎都指向使用 NSXMLParser 的类中的 1 行代码:

- (BOOL)parse{  
    NSURL *url = [[NSURL alloc] initWithString:@"[url here]"];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    [parser setDelegate:self];
    NSLog(@"NSXMLParser initialized");

    [parser parse];

    [url release];
    [parser release];
    return YES;
}

该工具指向将解析器创建为存在泄漏的行:

NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];

谁能指出我在这个问题上的正确方向?我已经在我的代码中检查了一个小时的引用计数,但没有运气。

更新:

好的,从 2 个答案中得到建议,我在创建 NSURL 之前添加了这些行:

[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];

我在发布解析器之前添加了这一行:

[parser setDelegate:nil];

每次添加都减少了泄漏的数量,现在我减少到了 2 个。CFNetwork 1 分,Foundation 作为负责库的 1 分。检查两者的调用堆栈根本没有显示我的任何代码。

还有什么我可能做错了吗?

【问题讨论】:

    标签: iphone objective-c cocoa-touch


    【解决方案1】:

    我在另一个帖子上找到了这个:

    [[NSURLCache sharedURLCache] setMemoryCapacity:0];
    [[NSURLCache sharedURLCache] setDiskCapacity:0];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    

    (来源:another stackoverflow topic

    但我还没有测试过这个解决方案。

    【讨论】:

    • bbum:你的意思是“不应该”吗?
    • 我试过了,现在 Leaks 确实显示了一些泄漏的对象,但是当我深入调用堆栈时,它都是框架方法,没有任何东西指向我的代码。这正常吗?
    • 是的......不应该不应该不应该算作泄漏。 :)
    【解决方案2】:

    您是否尝试在释放解析器的委托之前将其设置为nil?有些班级倾向于保留他们的代表......

    编辑:

    我实际上并没有看到解析器是NSXMLParser 实例。阅读文档我可以看到他们声明:“它没有被保留。”。我还是会试一试。

    【讨论】:

      【解决方案3】:

      如果这确实是您的全部代码,那么听起来确实像底层框架中存在泄漏。请压缩您的示例程序并file a bug

      但是,这并不是代码的全部——如果您的委托方法保留了任何内容并且没有与发布进行平衡,则会导致泄漏。混淆可能是因为泄漏工具显示了对象的分配点,而 实际 泄漏可能是由后续的retain 引起的。

      特别是使用 Object Alloc 工具和泄漏检测,您可以深入了解究竟是谁在保留和释放任何给定的对象。这可能会对情况有所帮助。

      【讨论】:

      • 或者,如果他省略了更多代码,他也应该粘贴。
      • 我有处理实际解析的委托方法,但由于泄漏没有指向它们中的任何一个,我认为它们不会是罪魁祸首。泄漏会指向调用方法而不是创建泄漏对象的位置吗?
      【解决方案4】:

      我遇到了同样的问题,我怀疑泄漏在底层框架中。

      我将代码更改为:

      NSXMLParser * parser = [[NSXMLParser alloc] initWithContentsOfURL:fileName];
      

      到这里:

      NSData * fileData = [[NSData alloc] initWithContentsOfURL:fileName];
      NSXMLParser * parser = [[NSXMLParser alloc] initWithData:fileData];
      [parser setDelegate:self];
      [parser parse];
      [parser release]; 
      [fileData release];
      

      泄漏消失了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-18
        • 1970-01-01
        • 2012-03-09
        • 2011-03-29
        • 2022-01-15
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多