1

メインスレッドがブロックされないようにしたいので、コアデータの保存をバックグラウンドで実行したいと思います。

私はこのリンク(および他の多くのリンク)と一緒にAppleドキュメントを読んでいます:http://www.cocoanetics.com/2012/07/multi-context-coredata/、しかし私はできませんアーキテクチャを正しくする。

私のAppDelegate.mで:

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _saveContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [_saveContext setPersistentStoreCoordinator:coordinator];

        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [_managedObjectContext setParentContext:_saveContext];
    }
    return _managedObjectContext;
}

次に、保存するために、次のようなことを行います。

// var 'context' is the context coming from method managedObjectContext
// this code is in the same thread 'context' is created in (the main thread)
NSError *error = nil;
if ([context save:&error]) {
    [context.parentContext performBlock:^{
        NSError *err = nil;
        if(![context.parentContext save:&err]) {
            NSLog(@"Error while saving context to the persistent store");
        }
    }];
} else {
    // handle error
}

これは私が以前に提供したリンクを読むことから得られるものです。保存は機能しません。アプリを閉じて再度開くと、管理対象オブジェクトに加えられた変更は失われます。永続化されたストアに保存されることはありません。

1つのスレッドで2つのNSManagedObjectContextを作成したので、Appleのドキュメントでは、スレッドごとに1つのNSManagedObjectContextしかないと明確に述べています。では、_managedObjectContextと_saveContextの間に親子関係を設定するにはどうすればよいですか?_saveContextを別のスレッドで初期化する必要があることは知っていますが、このアプローチを機能させることはできません。

4

1 に答える 1

0

(コメントより)

すべての「新しい」管理対象オブジェクトコンテキストタイプ(NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType)は、独自のスレッドを管理します。特別なスレッドでコンテキストを作成する必要はありません。覚えておくべき唯一のことは、常にコンテキスト内の操作に使用performBlockすることです。performBlockAndWaitこれにより、操作が適切なキューとスレッドで実行されるようになります。

だからあなたのコードは大丈夫です。

(結局のところ、エラーは、間違ったコンテキストが保存ルーチンに渡されたため、内部保存がトップレベルのコンテキストで実行されなかったことです。)

于 2013-02-21T09:08:10.720 に答える