web-dev-qa-db-ja.com

サブグラフ内のすべての変更を追跡/監視するにはどうすればよいですか?

NSManagedObjectContextがあり、その中にはNSManagedObjectsのいくつかのサブクラスがあり、一部は他のコンテナになります。私がしたいのは、トップレベルのオブジェクトを監視して、そのプロパティ、関連付け、またはオブジェクトに含まれるオブジェクトのプロパティ/関連付けのいずれかの変更が通知されるようにすることです。

コンテキストの「hasChanges」を使用しても、十分な粒度が得られません。オブジェクトの 'isUpdated'メソッドは、指定されたオブジェクトにのみ適用されます(その関連付けには何も適用されません)。サブグラフに限定されたコンテキストの変化を観察できたので、便利な(おそらくKVOベースの)ものでしたか?

58
David Carney

NSManagedObjectContextObjectsDidChangeNotificationをリッスンして、データモデルへのすべての変更を取得する必要があります。これは、次のようなコードを使用して実行できます。

[[NSNotificationCenter defaultCenter] 
      addObserver:self 
         selector:@selector(handleDataModelChange:) 
             name:NSManagedObjectContextObjectsDidChangeNotification 
           object:myManagedObjectContext];

これにより、myManagedObjectContextコンテキストへの変更時に-handleDataModelChange:がトリガーされます。

-handleModelDataChange:メソッドは次のようになります。

- (void)handleDataModelChange:(NSNotification *)note
{
    NSSet *updatedObjects = [[note userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[note userInfo] objectForKey:NSDeletedObjectsKey];
    NSSet *insertedObjects = [[note userInfo] objectForKey:NSInsertedObjectsKey];

    // Do something in response to this
}

ご覧のように、通知には、更新、削除、および挿入された管理対象オブジェクトに関する情報が含まれています。その情報から、データモデルの変更に応じて行動できるはずです。

129
Brad Larson

swiftの簡単な例を次に示します。

    NotificationCenter.default.addObserver(forName: .NSManagedObjectContextObjectsDidChange, object: nil, queue: nil) { note in
        if let updated = note.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject>, updated.count > 0 {
            print("updated: \(updated)")
        }

        if let deleted = note.userInfo?[NSDeletedObjectsKey] as? Set<NSManagedObject>, deleted.count > 0 {
            print("deleted: \(deleted)")
        }

        if let inserted = note.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject>, inserted.count > 0 {
            print("inserted: \(inserted)")
        }
    }
19
Ilias Karim

私にとっては、2つの機能の後に失われただけで、誰かの時間を節約できるかもしれません

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}
0
zmj110