Core Data, Batch-Updates und der Cache

Es kommt häufig vor, dass man eine große Anzahl von Datensätzen in einem Rutsch ändern muss. Dafür bietet Core Data den NSBatchUpdateRequest  an. Im nachfolgenden Beispiel wollen wir das Attribut visible  bei allen Datensätzen, bei denen es false  ist, auf true  setzen:

In dem Beispiel lassen wir uns über den ResultType UpdatedObjectsCountResultType  auch noch die Anzahl der geänderten Datensätze zurückgeben.

Und was ist mit dem Cache?

Ein Problem gibt es, wenn wir in anderen Objekten auf die gerade geänderten Daten zugreifen oder nach diesen filtern wollen. Core Data speichert nämlich alle NSManagedObject  in einem Cache und dort sind auch nach dem Update noch die alten Daten enthalten, bei denen visible  gleich false  ist. Um das zu umgehen, müssen wir die betroffenen Objekte neu laden und die gerade gemachten Änderungen berücksichtigen.

Der einfachste Weg dafür ist die eindeutige ObjectID, mit der Core Data jedes Objekt identifizieren kann. Praktischerweise können wir als resultType  gleich .UpdatedObjectIDsResultType  angeben und erhalten so als Ergebnis nicht die Anzahl der geänderten Datensätze, sondern eine Liste alle ObjectIDs. Dann müssen wir eigentlich nur noch die betroffenen Objekte holen und mit refreshObject  die Daten aktualisieren. Unser erweitertes Beispiel sieht dann so aus:

Als Ergebnis bekommen wir ein Array mit NSManagedObjectID  und holen uns von Managed Object Context das entsprechende NSManagedObject für die ObjectID. Weist das Objekt keinen Fehler auf, laden wir das Objekt mit refreshObject  neu und legen über mergeChanges:true  fest, dass die gerade gemachten Änderungen kombiniert werden sollen.

Danach haben alle betroffenen Objekte aktuelle Daten und auch ein Filter über die Objekte funktioniert.