Unten ist ein Link zum Download einer vereinfachten Version meiner App, die genau das gleiche Problem hat. Die Plus-Schaltfläche "Hinzufügen" oben fügt einen neuen Datensatz hinzu, der auf Name = 1, Menge = 1 und Abschnitt = 1 festgelegt ist. Durch Auswählen einer Zelle werden sie alle auf die nächste Zahl erhöht. Sie können sehen, dass sowohl der Name als auch die Menge aktualisiert werden, aber der Abschnitt wird nie aktualisiert, bis Sie die App beenden und erneut starten. DropBox Download LinkSection-Update-Ereignis wird nicht von verwandter Entität in swift aufgerufen
Ich habe folgende Beziehung Setup in Coredata:
In meinem Tableviewcontroller, ich meine FetchRequestController (FRC) mit dem folgenden Code erstellen:
func fetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Items")
let sortDesc1 = NSSortDescriptor(key: "catalog.sections.section", ascending: true)
let sortDesc2 = NSSortDescriptor(key: "isChecked", ascending: true)
let sortDesc3 = NSSortDescriptor(key: "catalog.name", ascending: true)
fetchRequest.sortDescriptors = [sortDesc1, sortDesc2, sortDesc3]
return fetchRequest
}
func getFCR() -> NSFetchedResultsController {
frc = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc, sectionNameKeyPath: "catalog.sections.section" , cacheName: nil)
return frc
}
Wie gezeigt, erstelle ich die Abrufanforderung für die Elementeinheit und sortiere nach Attributen in den Elementen Katalog und Abschnitte. Und speziell auf mein Problem, habe ich die Abschnitte Schlüssel in meinem frc als Abschnitt Attribut in der Abschnitt Entität (die durch die Catalog Entity verwandt ist).
Wenn ich verschiedene Teile der Artikel oder Katalog bin Aktualisierung ich die Tabellenzelle Update korrekt zu sehen (dh das didChangeObject Ereignis genannt wird)
Aber wenn ich den Abschnitt ändern aktualisiert es nie, wenn ich aus vollständig wieder von den Tisch und dann erneut eingeben. (d. h. das didChangeSection-Ereignis wird nie aufgerufen, obwohl sich der Abschnitt ändert)
Unten ist der Code, den ich verwende, um einen bereits vorhandenen Artikeldatensatz zu bearbeiten.
func editItem() {
let item: Items = self.item!
item.qty = Float(itemQty.text!)
item.catalog!.name = Util.trimSpaces(itemName.text!)
item.catalog!.brand = Util.trimSpaces(itemBrand.text!)
item.catalog!.qty = Float(itemQty.text!)
item.catalog!.price = Util.currencyToFloat(itemPrice.text!)
item.catalog!.size = Util.trimSpaces(itemSize.text!)
item.catalog!.image = UIImageJPEGRepresentation(itemImage.image!, 1)
if (self.section != nil) {
item.catalog!.sections = self.section
}
do {
try moc.save()
} catch {
fatalError("Edit Item save failed")
}
if (itemProtocal != nil) {
itemProtocal!.finishedEdittingItem(self, item: self.item!)
}
}
Just zu beachten, wenn ich in einem neuen Datensatz in der Item-Entity, die didChangeObject und didChangeSection Ereignisse sind beide richtig genannt hinzuzufügen. Nur wenn sie bearbeitet werden, wird didChangeSection übersprungen oder verpasst.
Nur zur Vervollständigung, unten ist mein Code, den ich für didChangeObject und didChangeSection verwende.
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case NSFetchedResultsChangeType.Update:
self.tableView.reloadSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Move:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Update:
self.tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Delete:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Insert:
self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
case NSFetchedResultsChangeType.Move:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
Als ich dieses Problem gegoogelt, fand ich, dass andere haben ähnliche Probleme wie diese hatten und es scheint ein Merkmal (oder Fehler) des FRC zu sein und wie Xcode Griffe Beziehungen. Im Prinzip beobachtet der Frc nur die Item Entity, und wenn sich die Section Entity ändert, wird sie nicht bei der Frc registriert. Die Leute haben auch verschiedene Hacks vorgeschlagen, aber bisher scheint keiner von ihnen für mich zu arbeiten. Beispiele sind, so etwas zu tun item.catalog.sections = item.catalog.sections
Keines der Beispiele hatte den Abschnitt Schlüssel als eine verwandte Einheit, so dass ich nicht sicher bin, ob das ist, warum sie nicht für mich arbeiten.
Also meine Frage ist, ob gibt es eine Möglichkeit, didChangeSection zu sagen, um auszuführen und senden Sie die richtige NSFetchedResultsChangeType? Oder noch besser, gibt es einen Weg, die FRC zu "ermutigen", um zu bemerken, was in der Sektionseinheit geschieht, die durch die Katalogeinheit mit der Item-Entität verbunden ist.
Das hat perfekt funktioniert! Danke für den Vorschlag. Ich konnte es auch auf der ursprünglichen App implementieren. Nur eine weitere Änderung, die ich vornehmen musste, bestand darin, 'fetchRequest()' 'ein Prädikat hinzuzufügen, da jeder Artikel einen zugehörigen Katalog hat, aber nicht jedem Katalog ein verwandtes Element zugeordnet ist. 'let pred = NSPredate (format:" items! = nil ")' & 'fetchRequest.predicate = pred' Es besagt, dass ich 6 Stunden warten muss, bevor ich das Bounty vergeben kann, aber ich werde versuchen, es heute Abend zu tun. –