1

我用循环重复调用一个函数,循环在一个线程内运行。该线程有一个自动释放池。

我在该函数中有以下代码:

NSXMLDocument* undoXML;
NSData* undoData = [NSData dataWithContentsOfFile:undoFilePath];
undoXML = [[NSXMLDocument alloc] initWithData:undoData 选项:NSXMLDocumentTidyXML 错误:&err];

NSData* 撤消数据2;
undoData2 = [undoXML XMLData];

[undoData2 发布];
[撤消XML释放];

我得到以下奇怪的结果:

  • 每次循环调用此函数时,我的程序都会泄漏内存。
  • 当我将以下代码添加到函数时:

NSData* 撤消数据3;
undoData3 = [undoXML XMLData];
[undoData3 发布];

我的程序比以前泄漏了更多的内存。

我真的很困惑,我非常需要帮助弄清楚发生了什么。也许我的自动释放池工作不正常?为什么会这样?

4

4 回答 4

2

你确定它在泄漏?或者它只是在扩大规模?

你的循环是什么样的?自动释放池是如何集成到其中的?

自动释放池必须在循环内,否则随着时间的推移,您的循环只会积累大量内存。泄漏工具没有显示泄漏表明您违反了内存管理规则或您的循环不正确。

于 2010-01-30T05:30:39.127 回答
1

尝试使用泄漏检测设置在您的项目上运行 Instruments。这应该准确地确定您的泄漏发生在哪里(即使在系统库中)。

运行 -> 使用性能工具运行 -> 泄漏

于 2010-01-30T04:10:56.037 回答
0

undoData应该预设为自动释放(根据命名约定dataWithContentsOfFile:返回一个自动释放的对象)。但是除非您有自己的自动释放池,否则设置为自动释放的任何内容实际上都不会被释放,直到活动池耗尽(即在您的函数返回后的某个时间)。

您的线程可能有自己的自动释放池,但除非您在自己的函数中创建一个,否则在您的函数退出之前不会释放任何内容。

如果你想在函数中间触发自动释放对象的耗尽(比如每个循环一次),你需要管理你自己的自动释放池。

while(looping) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // do stuff that produces autoreleased objects

    [pool drain];
}

此外,根据cobbal对您问题的评论,您似乎不应该发布undoData2(或undoData3)。根据命名约定-[NSXMLDocument XMLData]应该返回一个自动释放的对象。

于 2010-01-30T05:36:30.890 回答
-2

如果您有权访问 NSData 类的源代码,您应该查看在创建 undoData3 时正在实例化哪些对象。我这样说是因为您创建了对象并立即销毁它。问题一定是内存是在类内部分配的,但没有在它的析构函数中被释放。

于 2010-01-30T04:22:13.797 回答