0

アプリをロードするとき、約 10 ~ 15 個の JSON ファイルをダウンロードし、アプリのドキュメント ディレクトリに保存します。数 KB から 30 MB の範囲のものもあります。

それが完了したら、ドキュメント ディレクトリからそれぞれを取得し、NSDictionary に変換して、NSManagedObjects に解析する必要があります。

しかし、以下のコードでそれを行うと、アプリがクラッシュするまで、各 JSON をメモリに保持しているように見えます。Instruments の「Leaks」ツールには何も表示されませんが、私のアプリは大量のメモリを保持しています。

JSON ファイルを取得するコードは次のとおりです。

更新しました

- (void)parseDownloadedFiles
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];
    docDir = [docDir stringByAppendingString:@"/jsons"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;   
    NSArray *files = [fileManager contentsOfDirectoryAtPath:docDir error:&error];
    if (files == nil) {
        // error...
    }

for (NSString *file in files) 
{

    NSString *fileName = [NSString stringWithFormat:@"%@/jsons/%@",
                          docDir, file];
    NSString *content = [[NSString alloc] initWithContentsOfFile:fileName
                                                    usedEncoding:nil
                                                           error:nil];

    NSDictionary *JSON =
    [NSJSONSerialization JSONObjectWithData: [content dataUsingEncoding:NSUTF8StringEncoding]
                                    options: NSJSONReadingMutableContainers
                                      error: &error];


       ...create my NSManagedObjects & store

       JSON = nil;
    }  
}

--

私の割り当てを見てみましょう: ここに画像の説明を入力

--

その最初の Malloc 44.79 を掘り下げると、次の問題行が表示されます。

ここに画像の説明を入力

-- これは、上記のコードの for ループ内にあります。

ここに画像の説明を入力

その NSLog は本当にそのような問題を引き起こしますか?

4

2 に答える 2

1

ファイルを読み取るループ内に @autoreleasepool {} を配置する必要があります。メソッドが戻るまでオブジェクトは解放されないため、ループ内でメモリが蓄積されます。

ARC はオブジェクトを自動解放するのに役立ちますが、より速く解放する必要があります。

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

于 2013-02-02T00:16:42.857 に答える
1

はい、あなたの getContentFromFile... メソッドは保持された文字列を返しています。そして、受信側でそれを解放することはありません。

文字列を返すときに自動解放するか、JSON に解析した後に明示的に解放する必要があります。

(Analyzer がこれを見つけたと思います。)

于 2013-02-01T22:12:28.360 に答える