0

私はいくつかのテストを行ってきましたが、私のニーズの 1 つは、さまざまな xml ファイルからデータを読み取り、それを 1 つのファイルにまとめることです。私はこれを達成することができましたが、メモリ消費はタスクに対してかなり大きいようです.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];
    }

「Build and Analyze」コマンドを使用すると、リークなどは発生せず、ビルド時にコードで警告が発生することはありませんが、それでもメモリ消費量は 50 ~ 70 MB になります (ライブ バイトを考慮すると、全体的にはほぼ 2 倍になります)。
明らかに、同じファイルを 100 回読み取るという考えではありませんが、コードは xml ファイルからコンテンツを読み取って、受信した順序でファイルに送信するだけでよいため、テスト データとしては十分です。

新しいオブジェクトが割り当てられる前に、いくつかの一時オブジェクトを強制的に解放する方法はありますか?いくつかの変数を再利用しようとすることはできますか?これを制御下に置くのに役立つアイデアは大歓迎です。

編集- 物事をもう少し面白くするために: 単一のパーサーで読み取りと書き込みを行う方がよいでしょう。それによって、GDataXML を使い続けるか、変更が必要な場合は KissXML、TinyXML を使用するのが最善です。または libxml - DOM は、ここで述べたように、すべて少し多くのメモリを消費しているように見えるため、メモリの解放を強制する方法があれば、それが最適です。

前もって感謝します :)

4

2 に答える 2

1

実際、それは非常に単純な解決策でした。

私がしなければならなかったのは、AutoReleasePool をインスタンス化し、ループの最後でそれを排出することだけでした。
このような:

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

これにより、for 内でインスタンス化された autorelease としてマークされたオブジェクトが強制的に解放されました。これは、他のすべてに干渉することなく、予想どおり、終了後に解放されていたため、オブジェクトが解放される前に解放されませんでした。
メモリ消費量は、ループ中に 60 ~ 80 メガバイトから 1.6 メガバイト程度に減少し、その後は同じ 600 キロバイトに戻りました (これはダミー アプリケーションで行われました)。

誰かがより良いアイデアを持っている場合に備えて、この質問はしばらく開いたままにしますが、今のところ、これが方法になるようです:)

于 2010-08-13T20:39:12.663 に答える
0

そうですね、すべてを NSData に読み込んでから GDataXMLDocument の DOM に解析することで、それを「2 倍」にしました。このように大量の XML データを処理したり、複数のファイルをループしたりすることが予想される場合は、代わりに SAX ベースの解析を検討し、NSData にプリロードするのではなく、ファイルから直接ストリーミングすることを検討してください。そうすれば、「一時オブジェクトを解放する」必要がなくなります。必要な情報だけが解析されて抽出されるからです。

于 2010-08-11T21:28:51.417 に答える