web-dev-qa-db-ja.com

コアデータviewContextがNSFetchedResultsControllerを使用してnewBackgroundContext()から更新を受信しない

私のアプリケーションでは、UITableViewにコアデータオブジェクトをロードするNSFetchedResultsControllerがあります。このFRCに関連付けられたフェッチ要求は、viewContext(iOS10)で利用可能な新しいNSPersistentContainerプロパティを使用します。

セルを選択すると、Core Dataオブジェクトを新しいViewControllerに渡します。この新しいVCは引き続きviewContextを使用します。このViewControllerから、モーダル表示されたViewControllersからコアデータオブジェクトを更新できます。これを行うには、モーダルViewControllersにnewBackgroundContext()を使用します。更新コアデータオブジェクトを問題なく保存できます。

問題は、FRCがバックグラウンドコンテキストからの更新コアデータオブジェクトで自動的に更新されないことです。これは、viewContextが受信されておらず、Core Dataオブジェクトの更新を処理していないかのようです。

ViewContext(アプリ全体)でautomaticallyMergesChangesFromParentをtrueに設定した場合、背景コンテキストを保存すると、FRCは更新されたコアデータオブジェクトを取得します。私の理解では、viewContextはデータのマージを自動的に管理する必要があります。ドキュメントでは、viewContextを次のように説明しています。"このコンテキストは世代別であり、他のコンテキストからの保存通知を自動的に消費するように構成されています。"

NSFetchedResultsControllerでさまざまなコンテキストを処理する方法を明確にできますか?

31
alpennec

正しい動作が表示されています。 viewContextがnewBackgroundContext()によって作成されたコンテキストを含む他のコンテキストからの変更を自動的に取得するようにするには、automaticallyMergesChangesFromParenttrueに設定する必要があります。

ドキュメントがその点で混乱していることに同意します"...そして、他のコンテキストからの保存通知を自動的に消費します。"

32
Jerry

親からの変更を自動的にマージするには、次のようにviewContextに設定する必要があります。

persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
8
Ramis

私はこれに直接遭遇していませんが、newBackgroundContextが実際にviewContextの下に階層化されている場合、あなたの問題は奇妙な印象を与えます。永続ストアへの変更(適切に行われている)。その疑いに基づいて、私はAppleが言うところの開発者のドキュメントを見ました:

このメソッド(newBackgroundContext())を呼び出すと、永続コンテナは、concurrencyTypeがprivateQueueConcurrencyTypeに設定された新しいNSManagedObjectContextを作成して返します。これは新しいコンテキストはNSPersistentStoreCoordinatorに直接関連付けられますで、NSManagedObjectContextDidSaveブロードキャストを自動的に消費するように設定されています。

したがって、viewContextとの親子関係にはありません。ガイダンスに基づいて、新しいコンテキストには古いものによる変更が通知されますが、その逆ではないようです。そのため、新しいコンテキストが変更されたときに、viewContextを更新する必要があります。コードでそれを追跡するか、NSManagedObjectsContextの変更通知の1つを使用してアクションをトリガーします。

6
Ron Diel

私にはうまくいかなかったので、ブロックを保存から変更しました

self.persistentContainer.performBackgroundTask { (context) ... }

self.persistentContainer.newBackgroundContext().performAndWait { ... }

また、corseをtrueに設定すると、自動マージが機能するようにautomaticallyMergesChangesFromParentが設定されます。

lazy var viewContext: NSManagedObjectContext = {
    self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
    self.presistentContainer.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
    return self.persistentContainer.viewContext
}()

contextperformBackgroundTaskviewContextにマージされなかった理由がわかりません。

0
Vahid