0

ここに画像の説明を入力

これは、インストゥルメントを介してアプリを実行したときに得られるものです。多くのコアデータを処理しています。これは明らかに正しくないことがわかりますが、このスクリーンショットが何を伝えているのかよくわかりません。何が問題だと思われますか? 興味があれば、要約したコードは次のとおりです。

    NSFetchRequest *oldFetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *oldEntryEntity = [NSEntityDescription entityForName:@"Entry"
                                                      inManagedObjectContext:oldContext];

    [oldFetchRequest setEntity:oldEntryEntity];

    int numberOfEntries = [oldContext countForFetchRequest:oldFetchRequest error:nil];

    int batchSize = 4;
    [oldFetchRequest setFetchLimit:batchSize];
    int offset = 0;

    while (numberOfEntries - offset > 0) {
        @autoreleasepool {
        [oldFetchRequest setFetchOffset:offset];
        NSError *error;
        NSArray *entries = [oldContext executeFetchRequest:oldFetchRequest error:&error];

        for (NSManagedObject *entry in entries) {
        @autoreleasepool {
            Entry *newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"Entry"
                                                            inManagedObjectContext:newContext];

            newEntry.entryID = [entry valueForKey:@"entryID"];

            NSMutableOrderedSet *newMediaSet = [[NSMutableOrderedSet alloc] init];

            NSOrderedSet *mediaSet = [entry valueForKey:@"media"];

            int i = 0;

            for (NSManagedObject *media in mediaSet) {

                Media *newMedia = [NSEntityDescription insertNewObjectForEntityForName:@"Media"
                                                                inManagedObjectContext:newContext];

                newMedia.isInPhotoLibrary = [media valueForKey:@"isInPhotoLibrary"];
                newMedia.positionInEntry = [NSNumber numberWithDouble:i + 1];

                MediaImageData *imageData = [NSEntityDescription insertNewObjectForEntityForName:@"MediaImageData"
                                                                          inManagedObjectContext:newContext];

                imageData.data = [media valueForKey:@"originalImage"];

                newMedia.imageData = imageData;

                newMedia.entry = newEntry;
                [newMediaSet addObject:newMedia];

                i++;
            }

            newEntry.media = newMediaSet;


        }
        }

        [newContext save:&error];

        offset = offset + batchSize;
   }
}

編集:私はここで与えられたアドバイスに従い、@autoreleasepools(上記で編集しました)でラップしましたが、これが起こった後もクラッシュしました:

http://cl.ly/image/1U2T2p3w1X2Z

明らかに最初よりもコードに深く入り込みましたが、まだクラッシュしています。

4

3 に答える 3

2

コードの効率性について議論することなく:外部 (while) ループと内部 (for) ループの両方で
コードをラップします。 それ以外の場合は、大量のメモリを割り当てて、外側のイベント ループがループの最後に到達したときにのみ解放します。@autoreleasepool {}

于 2012-09-17T12:25:18.493 に答える
1

まず、Core Data 関連の質問を投稿する際のちょっとしたアドバイスです。情報が多すぎるということはほとんどありません。詳細を省略すると、可能な相互作用が非常に多くなるため、人々があなたを助けることが非常に難しくなります.

投稿したコードを見るだけで、非常に多くの疑問が残ります。

割り当ての数ではなく、全体のサイズでソートされた情報を見たいと思います。これにより、メモリがどこで使用されているかがより簡単にわかります。そのままでは、その写真のどこでメモリが使用されているかわかりません(また、古い目で、拡大するとぼやけすぎます)。

それがコア データに関係していると思われる場合、なぜコア データ インストゥルメントを実行しないのですか?

いくつかの診断支援に進みます。

新しい MOC は PSC に直接接続されていますか、それとも親 MOC がありますか。親 MOC がある場合、保存は親 MOC に押し込まれ、保存がデータベースに永続化されるまでメモリに残ります。

mediaSet にはいくつのアイテムがありますか? それらがたくさんある可能性があり、メモリを食いつぶす可能性があります。

FetchRequest と MOC にどのパラメーターを適用しましたか? これらのオプションに基づいて、MOC はオブジェクトを保持している可能性があります。これを確認する方法は、各 MOC の保持/挿入/削除/etc セットのカウントをログに記録することです。それらをログに記録することで、どちらかの MOC が保持すべきでないと思われるものを保持しているかどうかを確認できます。

次に、MOC を更新/リセットする必要があるかどうかを知ることができます。

チート[moc reset]して保存後に呼び出すこともできますが、その前後の数字を確認して、メモリがどこにあるかを自分で確認できると便利です。

さらにデバッグを行います。適切な決定を下せるように、より多くの情報を提供してください...そうすれば、私たちもあなたを支援するためのより良い情報を得ることができます.

編集

おっと。おそらくメモリが多すぎないというコメントを削除しました。私の古い目は、その画像の小さなプリントを見るのに何の役にも立ちませんでした。

編集

ありがとう。各 MOC の保持/挿入/削除されたセットの数をログに記録するにはどうすればよいですか? – アンドリュー

MOC には、これらのカテゴリに一致する一連のオブジェクトを提供するいくつかのプロパティ ( registeredObjectsinsertedObjectsdeletedObjects、 ) があります。updatedObjects単純NSLogに各カテゴリのオブジェクトの数です。MOC ごとに、MOC が長期にわたって追跡しているオブジェクトの数を確認できます。

また、コア データ インストゥルメントを有効にします。彼らは本当に有益です。

于 2012-09-17T15:42:19.283 に答える
1

高速列挙(forループ)の内部を でラップしてみてください@autoreleasepool。これが役立つはずです。また、何らかのカウンターを実行して、変更が危険なメモリ消費に達したときにコンテキストをループ内に保存することもできます。

確かにたくさんのオブジェクトがありますが、データ構造を最適化することを考えてください。

于 2012-09-17T12:24:49.570 に答える