[CoreData] Relationship in Swift nach Aktualisierung

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • [CoreData] Relationship in Swift nach Aktualisierung

    Ich habe zwei Tabellen mit einer 1 : n Beziehung. Tabelle 1 ist vereinfach gesagt ein Begriff und Tabelle 2 ein Thema. Jeder Begriff ist einem Thema zugeordnet und jedes Thema kann entsprechend auf viele Begriffe verweisen. Die Models sehen dann vereinfach so aus:

    Quellcode

    1. class Begriff: NSManagedObject
    2. {
    3. @NSManaged var visible: Bool
    4. @NSManaged var thema: Thema
    5. }
    6. class Thema: NSManagedObject
    7. {
    8. @NSManaged var begriffe: NSSet
    9. var visibleCount: Int {
    10. get {
    11. return self.begriffe.filteredSetUsingPredicate(NSPredicate(format: "visible == %@", true)).count
    12. }
    13. }
    14. }
    Alles anzeigen

    Die Tabelle 1 Begriff hat ein Attribut visible, nach welchen in in bestimmten Fällen selektieren möchte.

    Mein Problem ist nun, sich im Model Thema das NSSet absolut nicht ändern will. Ich ändere den Wert visible für einige Objekte und speichere diese. Danach hole ich mir alle Themen über einen FetchRequest neu und trotzdem liefert mir meine visibleCount-Funktion die Anzahl der vorher sichtbaren Begriffe. Die Begriffe wurden jedoch richtig gespeichert, da nach einem Neustart der App alles richtig angezeigt wird.

    Kann mir irgendwer auf die Sprünge helfen, wo ich das Problem suchen kann? Als Workaround habe ich jetzt folgende Methode implementiert, die aber natürlich deutlich langsamer ist:

    Quellcode

    1. class Thema: NSManagedObject
    2. {
    3. var _visibleCount: Int {
    4. var error: NSError? = nil
    5. let fetchRequest = NSFetchRequest(entityName: "Begriff")
    6. fetchRequest.resultType = .CountResultType
    7. fetchRequest.predicate = NSCompoundPredicate(type: .AndPredicateType, subpredicates: [
    8. NSPredicate(format: "visible == %@", true),
    9. NSPredicate(format: "thema == %@", self)
    10. ])
    11. if let result = self.managedObjectContext!.executeFetchRequest(fetchRequest, error: &error) as? [NSNumber]
    12. {
    13. return result[0].integerValue
    14. }
    15. return 0
    16. }
    17. }
    Alles anzeigen
    Die liefert mir immer den richtigen Wert aber sol will ich es eben nicht machen.
    So Long, and Thanks for All the Fish.
  • Mittlerweile habe ich die Lösung gefunden und will sie nicht vorenthalten, falls mal jemand ein ähnliches Problem hat. Der Fehler kam daher, dass ich das visible Attribut in einem NSBatchUpdateRequest gesetzt habe. Wie ich jetzt herausgefunden habe, werden damit jedoch nicht die schon im NSManagedObjectContext vorhandenen Objekte aktualisiert – das muss man manuell selber machen. Vereinfach sieht das so aus:

    C-Quellcode

    1. let batchRequest = NSBatchUpdateRequest(entityName: "Entity")
    2. batchRequest.predicate = NSPredicate(format: "visible == %@", false)
    3. batchRequest.propertiesToUpdate = ["visible" : true]
    4. batchRequest.resultType = .UpdatedObjectIDsResultType
    5. var error: NSError? = nil
    6. if let request = self.managedObjectContext!.executeRequest(batchRequest, error: &error) as? NSBatchUpdateResult
    7. {
    8. if let resultObjectIDs = request.result as? [NSManagedObjectID]
    9. {
    10. for objectID in resultObjectIDs
    11. {
    12. let managedObject = self.managedObjectContext.objectWithID(objectID)
    13. if !managedObject.fault
    14. {
    15. self.managedObjectContext!.refreshObject(managedObject, mergeChanges: true)
    16. }
    17. }
    18. }
    19. }
    Alles anzeigen
    Wichtig ist hier, mit .UpdatedObjectIDsResultType die NSManagedObjectIDs zurückzubekommen und diese dann manuell zu aktualisieren. Danach sind alle Objekte auf dem richtigen Stand.
    So Long, and Thanks for All the Fish.