メインスレッドにNSFetchedResultsController
があります。また、メインスレッドから、私は非同期にJSONのネットワークリクエストを送信します。そのJSON文字列が返ってくると、新しい(背景)NSManagedObjectContext
を挿入し、JSON文字列を解析し、NSManagedObject
を作成してコンテキストに保存するNSOperation
を開始します。バックグラウンドコンテキストは、メインコンテキストと同じpersistentStoreを持ちます。私は任意の(任意のスレッド上の)任意のコンテキストから、永続ストアに保存されますが、変更がありますが、これまでのところ、それは選択しないことが主なNSFetchedResultsController
に通知するだろうと思っメインスレッドでNSFetchedResultsControllerを無視すると、別のスレッドからCore Dataに保存されますか?
:これで、私は2つの質問を持っています変更を取り消すメインスレッドの
NSFetchedResultsController
に外部save
があることを通知するために何かする必要があるので、それに応じてtableView
が更新されますか?ので、メインスレッド上で、私は
AppDelegateでNSManagedObjectContextWillSaveNotification
に加入し、(別のスレッドに完全に既存のものを含む)すべてのコンテキストがsave
操作を実行するときに正しく表示されます。 apple docsは、notification.userInfo
に、バックグラウンドスレッド上の「更新された、削除された、挿入された」モデルオブジェクトのそれぞれに対して3つの配列、1つの配列の辞書が必要であると言う。ただし、私にとってuserInfo
は常にnil
です。私が間違っていることは何ですか?NSManagedObjectContextWillSaveNotification
への登録
:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
や状況がAppDelegate内に保存されているときのための方法:
- (void)managedObjectContextDidSave:(NSNotification *)notification {
DLog(@"notification: %@", notification); //not nil
DLog(@"notification user info: %@", notification.userInfo); // always nil... why??
NSManagedObjectContext *theContext = notification.object;
if(theContext != context) {
DLog(@"---- SAVED ON ANOTHER CONTEXT");
// should I notify NSFetchedResultsController that there were context saves on background threads?
// how can I merge contexts if userInfo is nil?
}
}
私ものベストプラクティスを知りたいのですが複数のスレッド(別々のNSManagedObjectContextを持つ)とコアデータを扱います。
素晴らしい! userInfoは正しい辞書で埋められるようになりました。 'NSFetchedResultsController'に変更について通知するのはどうですか?これらの変更をメインコンテキストにマージすることをお勧めしますか?NSFetchedResultsControllerを更新する簡単な方法はありますか? – johngraham
コントローラはメインのコンテキストに依存しているため、これを行う正しい方法(実際には唯一の方法)は、変更をそのコンテキストにマージすることです。 – paulbailey
はい、 ' - [NSManagedObjectContext mergeChangesFromContextDidSaveNotification:]'を使って変更をマージするようにメインコンテキストに指示する必要があります。 'NSFetchedResultController'にデリゲートがあれば自動的に内容を更新し、デリゲートへの変更を通知します。それ以外の場合は、 'performFetch:'を送信してコンテンツをリロードすることができます。 –