我一直在做一些测试,我的需求之一是从不同的 xml 文件中读取数据并将其堆叠在一个文件中。虽然我已经成功地完成了这一点,但该任务的内存消耗似乎相当大,iPhone模拟器甚至没有提出内存警告,但我认为真正的iPhone不会容忍这种情况(我没有一个可以在这里尝试的设备,所以我主要是根据我所读到的内容推测的)。
代码(的主要部分)如下:

Boolean success = [fileManager createFileAtPath:documentsPath contents:nil attributes:nil];
[fileManager release];

if (success) {
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:documentsPath];
    for (int i = 0; i < 100; i++) {

        NSString *path = [[NSBundle mainBundle] pathForResource:@"mensagem_de_arquivo" 
                                                         ofType:@"xml"];
        NSData *data = [NSData dataWithContentsOfFile:path];
        GDataXMLDocument *xml = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
        NSArray *tokens = [xml nodesForXPath:@"//message/data" error:nil];
        if (tokens.count > 0) {
            GDataXMLElement *token = (GDataXMLElement *)[tokens objectAtIndex:0];
            [fileHandle writeData:[[token stringValue] dataUsingEncoding:NSASCIIStringEncoding]];
        }
        [xml release];
    }

使用“构建和分析”命令不会给我带来任何泄漏或任何问题,并且代码在构建时不会发出警告,但内存消耗仍然在 50 到 70mb 之间(仅考虑活动字节,总体而言几乎翻倍)。
这个想法显然不是读取同一个文件 100 次,但作为测试数据就足够了,因为代码必须从 xml 文件中读取内容并按照接收顺序将它们发送到文件。

有什么方法可以在分配新对象之前强制释放一些临时对象,我可以尝试重用一些变量吗?任何帮助我控制这种情况的想法都非常受欢迎。

编辑 - 只是为了让事情变得更有趣:最好保留一个解析器来读写,最好的方法是坚持使用 GDataXML,或者,如果需要更改,使用 KissXML、TinyXML 或 libxml - DOM,这些似乎都很糟糕正如所说,多一点内存 这里, ,所以如果有办法强制释放内存那就最好了。

提前致谢 :)

有帮助吗?

解决方案

事实上,这是一个非常简单的解决方案。

我所要做的就是实例化一个 AutoReleasePool 并在循环结束时耗尽它。
像这样:

for (int i = 0; i < 100; i++) {
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
    //... do everything I've done before...
    [pool drain];
}

这迫使释放在 for 中实例化的标记为 autorelease 的对象,这些对象只是在它结束后被释放,正如预期的那样,不会干扰其他一切,因此没有对象在它们应该释放之前被释放。
在循环期间,内存消耗从惊人的 60 ~ 80mb 下降到 1.6mb 左右,并在循环后回到相同的 600kb(这是一个虚拟应用程序,就是这样做的)。

我仍然会暂时保留这个问题,以防有人有更好的想法,但就目前而言,似乎就是这样:)

其他提示

是的,您通过将其全部读入 NSData,然后解析为 GDataXMLDocument 中的 DOM,将其“加倍”。如果您希望像这样处理大量 XML 数据、循环多个文件等,那么您应该 考虑使用基于 SAX 的解析, ,并直接从文件中流式传输,而不是将其预加载到 NSData 中。这样,您就不必“释放临时对象”,因为您只需在解析时提取所需的信息。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top