1

簡単な質問です。コア データ スタック (子/親) コンテキストがあります。子はjson objをフェッチして解析し、それらを親に保存します。カウントが20になると、親はメインスレッドを取得して保存します...すべて正常に動作します。ただし、私のテーブルビューでは、毎回データベース全体を再フェッチする必要があります! 私のフェッチカウントと期間はこれに大きな影響を与えます。誰か私にアイデアを教えてもらえますか? よろしくお願いします!また、何らかの理由で [[[SharedStore ShareStoreManager]getMasterContext] reset] は正常に動作します... ただ、mergeChangesFromContext ではありません!

NSNotificationCenter *mergeNotification = [NSNotificationCenter defaultCenter];
[mergeNotification addObserver:self
                      selector:@selector(mergeChanges:) 
                          name:NSManagedObjectContextDidSaveNotification 
                        object:[[SharedStore ShareStoreManager]getMasterContext]]



-(void)mergeChanges:(NSNotification *)notification {
     [[[SharedStore ShareStoreManager]getMasterContext] mergeChangesFromContextDidSaveNotification:notification];
     [self.tableView layoutIfNeeded];
     [self.tableView reloadData];
}  

編集:コンテキストオブジェクトに行って、マージされていない挿入されたアイテムを見たので、そこに強制的に行きましたが、それでも運がありません!!!

for (User *user in [[notification.userInfo objectForKey:@"inserted"] allObjects]) {
        [[[SharedStore ShareStoreManager]getMasterContext] refreshObject:user mergeChanges:YES];
    }
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}
4

1 に答える 1

1

私はあなたのデザインを再考NSFetchedResultsControllerし、あなたのオブジェクトのフェッチを行うために a を使用します。データ ソースにそのクラスを使用することの優れた点は、管理対象オブジェクト コンテキストで状況が変化したときに自動的に通知を受け取ることです。デリゲート コールバックを実装することで、テーブル ビュー内の適切な行を挿入、削除、移動、変更することで、フェッチされた結果コントローラーのデータの変更にテーブル ビューを応答させることができます。

これは、すべてを接続する方法を段階的に概説するチュートリアルです。

編集: コードを見ると、オブザーバーを追加すると、マスターコンテキストで発生する保存のみをリッスンします。バックグラウンド処理を行うために別のコンテキストを使用している場合、この通知はそのバックグラウンド コンテキストに対してのみ公開されるため、オブザーバーはトリガーされません。メイン コンテキストがその通知をトリガーする唯一の方法は、バックグラウンド コンテキストをメイン スレッド コンテキストとマージし、メイン スレッド コンテキストを保存する場合です。

コア データ スタック クラスには、すべての保存イベントをリッスンする独自のオブザーバーが必要です。

[[NSNotificationCenter defaultCenter] addObserver:sharedController
                                         selector:@selector(contextDidSave:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:nil];

次に、メイン スレッドのさまざまなスレッドとコンテキストで発生した変更をマージする必要があります。

- (void)contextDidSave:(NSNotification *)notification {
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self contextDidSave:notification];
        });
    } else {
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
    }
}

ここで、メイン コンテキストがメイン スレッドで作成され、スレッド セーフではないため、メイン スレッドでマージを実行していることを確認していることに注意してください。マージが完了すると、 などのオブザーバーに通知が送信されNSFetchedResultsController、独自のデリゲート コールバックがトリガーされ、UI を更新する機会が与えられます。

于 2013-07-06T04:16:47.983 に答える