3

Ich verwende NSFetchedResultsController mit einer UITableView, die eine Liste der Ordner und zugehörigen ungelesenen Zähler für jedes Element in diesem Ordner anzeigt. Ich möchte Ordner mit Animation aus dem TableView einfügen/löschen, basierend auf der ungelesenen Anzahl während einer Synchronisierung/Aktualisierung (auf einem Hintergrund-Thread mit NSManagedObjectContextDidSaveNotification). Ordner mit ungelesenen Elementen sollten ausgeblendet werden und vorhandene Ordner mit neuen ungelesenen Elementen sollten eingeblendet werden.Aktualisieren/Einfügen vorhandener Objekte in NSFetchedResultsController

Derzeit wird die Methode controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: nicht verwendet, es sei denn, das TableView wird vollständig neu geladen, oder die App wird neu gestartet, was nicht ideal ist .

Ist NSFetchedResultsController nicht der Weg, dies zu tun? Meine anfängliche Idee war es, eine separate Core Data-Entität zu erstellen, die nur die Ordner mit ungelesenen Elementen enthält und Ordner daraus hinzufügt/entfernt, aber das scheint nur hokey zu sein.

Mein NSPredicate sieht ungefähr so ​​aus:

ANY items.unread == 1

Update: Die obige NSPredicate funktioniert gut und packt die Objekte, die ich es erwarte. Mein Problem ist, dass wenn die App gestartet wird und FolderX 0 ungelesene Elemente hat, wird es nicht angezeigt. Wenn ich dann aktualisieren (erlischt und analysiert eine JSON-Datei in einem Hintergrund-Thread) und FolderX hat jetzt 25 ungelesene Elemente, wird es nicht automatisch verblassen oder NSFetchedResultsChangeInsert auslösen und da es nicht an erster Stelle enthalten war, es auch löst nicht NSFetchedResultsChangeUpdate aus, weshalb ich dachte, die Lösung bestünde darin, eine separate Entität zu erstellen, die nur Ordner mit ungelesenen Elementen enthält und diese während der Synchronisierung hinzufügen/entfernen.

Ich fühle mich nur wie ich etwas schmerzhaft offensichtlich vermisse.

Update 2: ich das Problem, so viel wie ich kann vereinfacht habe durch den Einfluss meiner eigenen App zu entfernen, ich bin der Lage, es in der Standard-Core Data-Vorlage in Xcode zu replizieren. Das neue Problem: Es gibt eine einzige Entität mit dem Namen "Event" ohne Beziehungen und zwei Eigenschaften, "Date" und "unreadCount". Ich habe festgelegt NSFetchedResultsController mit einem NSPredicate, die wie folgt aussieht:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"unreadCount < 10"]; 

Jedes Mal, wenn ein neues Objekt hinzugefügt wird, es mit einem UNREADCOUNT von 15 erstellt wird, werden alle vorhandenen Objekte um 1 verringert werden auf einem Dies ist getan separaten ManagedObjectContext (um die Hintergrundverarbeitung zu replizieren, aber alles im Hauptthread).

Ich habe die controllerWillChangeContent und verwandte Methoden implementiert, und was ich erwartet hatte, war, dass, nachdem ein vorhandenes Objekt (mit unreadCount von 15) dekrementiert 5 mal (bis jetzt 10) sollte es in der Tabelle eingefügt werden, weil es stimmt jetzt mit dem Prädikat überein. Dies ist überhaupt nicht der Fall, das Objekt wird erst angezeigt, wenn die App neu gestartet wird.

Ich habe ein Beispielprojekt angehängt, starte es einfach und klicke ein paar Mal auf die Schaltfläche Hinzufügen (nichts wird passieren). Starten Sie die App neu und Sie sehen nun eine Handvoll Objekte in der Tabellenansicht. Wenn Sie noch einmal auf die Schaltfläche Hinzufügen klicken, entfernen sich diese Objekte selbst, aber neue Objekte werden nicht hinzugefügt.

Wenn NSFetchedResultsController nicht die Lösung ist, um dieses Verhalten zu funktionieren, was ist dann?

Beispielprojekt: http://dl.dropbox.com/u/521075/BGUpdating.zip

+0

was war Ihre Lösung für dieses Problem? Weil ich eine ähnliche Frage habe: http://stackoverflow.com/questions/12776371/gmgridview-with-nsfetchedresultscontroller-data-not-updating-reloading – acecapades

Antwort

1

Ihr Prädikat wird nicht funktionieren Kreuzung zwei oder mehr zu-viele-Beziehungen. Sie haben zur Zeit:

type == folder AND ANY (set of folders).(set of items).unread == 1 

Sie können keine verwenden, um eine beliebige Anzahl von Beziehungen zu transversieren. Stattdessen müssen Sie wahrscheinlich ein subquery wie:

type == folder AND (0!=SUBQUERY(folder,$f,0!=SUBQUERY($f.items,$i,$i.unread==1)[email protected])[email protected]) 

Ich glaube, Sie vielleicht die auf der falschen Einheit holen durchführen. Wenn Sie eine Tabelle mit Folder Objekten präsentieren, sollten Sie den Abruf auf der Folder Einheit ausführen. Das allein würde alles vereinfachen. Ihr Prädikat wäre dann nur:

ANY items.unread==1 
+0

Ich habe meine Frage aktualisiert, um ein wenig einfacher und klarer zu sein, und auch die To-Viele-Beziehung entfernt und die Ordner-Entität direkt abgerufen, aber immer noch nicht die Ergebnisse erhalten, die ich erwarte. – kaptin

+0

Das Problem scheint dann mit der Benachrichtigung nach der Zusammenführung zu sein. Die Zusammenführung sollte den FRC dazu veranlassen, seinem Delegierten mitzuteilen, dass sich etwas geändert hat. Stellen Sie sicher, dass inverse Beziehungen im Datenmodell festgelegt sind, sodass sich eine Änderung im Ordner oder Objekt auf der anderen Seite der Beziehung widerspiegelt. – TechZen

+0

Danke für die Hilfe, ich habe ein bisschen tiefer gegraben und meine Frage noch einmal aktualisiert, um noch spezifischer zu sein, indem ich den Einfluss meines eigenen App-Modells beseitige. – kaptin

Verwandte Themen