NSFetchedResultsController konsistente Verzögerung beim Aktualisieren der UITableView-Zelle; Einfügen funktioniert sofort

8

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:

%Vor%

Andere Dinge, die ich in case NSFetchedResultsChangeUpdate:

ausprobiert habe
  1. Der Aufruf von processPendingChanges vor dem Kontext save wurde versucht
  2. Aufruf von reloadRowsAtIndexPaths anstelle von configureCell direkt
  3. Versucht, die update .. Methoden innerhalb von beginUpdates und endUpdates zu wickeln (obwohl ich bereits ein Paar habe, das den Job erledigen sollte)
  4. [tableView reloadData]
  5. numberOfRowsInSection ist nicht 0!
  6. Die Methoden 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?

    
Kedar Paranjape 10.03.2015, 07:10
quelle

1 Antwort

4

@ 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.

    
Kedar Paranjape 10.03.2015, 11:41
quelle