Ich habe ein UITableView
(mit benutzerdefinierten Zellen, wenn das wichtig ist) mit einem NSFetchedResultsController
verbunden. Meine App verwendet auch Push-Benachrichtigungen. Wenn eine Remote-Benachrichtigung eintrifft, aktualisiere ich mein (Kern-) Datenmodell in zwei Phasen:
1) Erhalte Titel (mit einigen benutzerdefinierten Daten) und speichere ihn als neue Kerndaten Entity
. Hier rufe ich NSManagedObjectContext save()
an. NSFetchedResultsController
nimmt die Einfügung auf und löst ihre Delegate-Methode didChangeObject
mit NSFetchedResultsChangeType
= NSFetchedResultsChangeInsert
. Die Tabellenansicht wird sofort aktualisiert. (Eine neue Zeile wird eingefügt)
2) Laden Sie weitere Inhalte, die sich auf die Zelle beziehen, über NSURLSession
in die obige Entity
und rufen Sie erneut save() method
auf. NSFetchedResultsController
nimmt die Aktualisierung erneut auf und löst ihre Delegate-Methode didChangeObject
mit NSFetchedResultsChangeType
= NSFetchedResultsChangeUpdate
aus. Hier rufe ich meine Methode configureCell
auf. Das TableView wird aktualisiert, jedoch mit einer konsistenten Verzögerung von etwa 10 Sekunden.
In beiden Phasen (download-context save-update tableview) wurden die Daten, die angezeigt werden sollen, bereits von den Kerndaten beibehalten. (Zum Beispiel innerhalb meiner configureCell..
-Methode, ich weiß, dass ich kein Zellenlabel auf nil
oder ähnliches setze.
Meine NSFetchedResultsController
Delegiertenmethoden:
Andere Dinge, die ich in case NSFetchedResultsChangeUpdate:
processPendingChanges
vor dem Kontext save
wurde versucht
reloadRowsAtIndexPaths
anstelle von configureCell
direkt beginUpdates
und endUpdates
zu wickeln (obwohl ich bereits ein Paar habe, das den Job erledigen sollte) [tableView reloadData]
numberOfRowsInSection
ist nicht 0! NSFetchedResultsController
delegate werden nur im Hauptthread ausgeführt. Kurz gesagt, alle (?) richtigen Delegiertenmethoden werden korrekt aufgerufen. Dennoch sehe ich eine konsistente ~ 10 Sekunden Verzögerung beim Aktualisieren einer Zelle. Die Insertion erfolgt jedoch fast augenblicklich. Irgendwelche Ideen?
@ Paulw11s Kommentar über dispatch_async...
setzte mich in die richtige Richtung. Das Problem liegt in der Tatsache, dass ich das gleiche ManagedObjectContext
-Objekt in zwei verschiedenen Threads verwendet habe, obwohl sie nicht gleichzeitig auf es zugreifen. Sobald ich meine save
-Aufrufe (die in einem Hintergrundthread waren) in der Hauptwarteschlange (durch Einschließen in dispatch_async(dispatch_get_main_queue,^{ UIUpdate code here });
) versandt hatten, verschwanden die Verzögerungen. Eine mögliche Erklärung wäre, dass das Aufrufen von save
in einem Hintergrundthread dazu führt, dass die Delegatmethoden im Hintergrundthread aufgerufen werden.
Wie auch immer, zurück zur Lösung - teilen Sie niemals das gleiche ManagedObjectContext
-Objekt zwischen mehreren Threads. Verwenden Sie übergeordnete / untergeordnete Kontextbeziehungen , wenn Sie das Kerndatum in mehreren Threads aktualisieren. NSFetchedResultsController
spielt auch gut mit diesem Muster.
Tags und Links objective-c uitableview ios core-data nsfetchedresultscontroller