0

アプリの更新を書いています。db 30 画像内に挿入する必要があります。現在、私はコアデータを使用しており、正しく保存されますが、10 秒かかります...そのため、保存プロセスをバックグラウンドで送信することにしました。画像配列を操作する for サイクルがあり、各ターンで NSmanagedObject を作成して保存します。このベースでは、別のソリューションを試しましたが、何も正しく機能しません:

1 -----------------------

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    NSManagedObjectContext *contextTemp = [[NSManagedObjectContext alloc] init];
    NSPersistentStoreCoordinator *store=[(RecipesAppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
    contextTemp.persistentStoreCoordinator=store;

    Recipe *recipe = (Recipe *)[contextTemp objectWithID:MoID];


    NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:contextTemp];
    [image setValue:[[ArrayDizionariImmagini objectAtIndex:i] valueForKey:@"image"] forKey:@"image"];
    [image setValue:[NSDate date] forKey:@"data"];

    recipe.image=image;
    [contextTemp save:nil];


});

この方法はすべて正しい方法で保存しますが、メインスレッドでの最初の試行と同じように10秒かかるため、役に立ちません...

2------------------------------------------------- ----

dispatch_queue_t request_queue = dispatch_queue_create("com.doeatraw.saveimages", NULL);
dispatch_async(request_queue, ^{

    // Create a new managed object context
    // Set its persistent store coordinator
    AppDelegate *theDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *newMoc = [[NSManagedObjectContext alloc] init];
    [newMoc setPersistentStoreCoordinator:[theDelegate persistentStoreCoordinator]];

    // Register for context save changes notification
    NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
    [notify addObserver:self
               selector:@selector(mergeChanges:)
                   name:NSManagedObjectContextDidSaveNotification
                 object:newMoc];


    BOOL success = [newMoc save:nil];

});
dispatch_release(request_queue);

- (void)mergeChanges:(NSNotification*)notification
{

    context = [(RecipesAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    [context performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

この試行では、すべての更新の最後にのみ一時的な ManagedObjectContext を保存してから、変更をマージしようとします。このようにして、すべての画像をバックグラウンドで保存でき、UI は常に応答性を保ちます。しかし、アプリを閉じて再度開くと、すべての貯蓄が失われます...そのため、コア データが実際にはマージされていないことが明らかになりました。

3------------------------------------------------- -----------

また、すべてのデータをSQLで直接挿入しようとしました。私はすべてをバックグラウンドに置きましたが、問題ないようです.UIは応答性が高く、すべてのデータが挿入されています...とにかく何かがうまくいかない. 同じテーブルにアクセスしようとすると (同じテーブルに問い合わせるアプリで他の独立したメソッドを起動することによって)、SQL はログにエラーなしでアプリをクラッシュさせます (「制約に失敗しました」というエラーを受け取ったのは 1 回だけです)。挿入された画像を抽出して視覚化することはできますが、テーブルに (コア データによって) 別の挿入を行うことはできません。

誰かが私を助けることができますか?NSManagedObjectContext がスレッドセーフではないことは知っていますが、いくつかの試行でドキュメントのガイドラインに従おうとしました...何かが欠けているかもしれません...保存しようとしているのは、画像を関係として持つ nsmanagedobject です。コンテキストを実際にマージするにはどうすればよいですか? または、エラー sqlite Constraint Failed で何ができますか?

4

1 に答える 1

1

ほとんどの場合、オーバーヘッドは、画像を保存するたびに新しいコンテキストを作成することによって発生します。それは費用のかかる操作です。必要なコンテキストは2つだけです。1つはメインキュー用で、もう1つはシリアルバックグラウンドキュー用です。また、Appleは画像をデータベースに保存しないようにアドバイスしていることに注意してください。私が経験したことは、同じことを言っています。データベースにはイメージパスのみを保持し、ファイルシステムにはイメージを保持する必要があります。

于 2012-12-13T19:21:21.390 に答える