Kerndaten: Hintergrund abrufen, NSFetchedResultsController und Sortierzeit

8

Das Problem, auf das ich stoße, ist folgendes:

Ich habe ein UITableView , das ich mit Daten aus einem NSFetchedResultsController füttere, das ungefähr 6000 Zeilen aus den Kerndaten abruft. % Co_de% von fetchBatchSize wird auf 20 gesetzt und wenn ich NSFetchRequest nicht anwende, ist das Fetch schnell genug, um den UI-Thread nicht zu blockieren.

Allerdings muss ich diese Zeilen alphabetisch sortiert anzeigen, für die ich den folgenden NSSortDescriptor verwende:

%Vor%

Und wenn sich die Dinge ändern, dauert der Abrufvorgang jetzt etwa 3 Sekunden, weil die 6000 Zeilen sortiert werden. Offensichtlich ist die Benutzeroberfläche während dieser Sekunden blockiert und die Benutzererfahrung ist schrecklich.

Ich weiß, dass ich den Abruf in einem Hintergrundthread machen und dann zu Objekt-IDs an den Hauptthread übergeben kann, aber in diesem Fall könnte ich immer noch NSSortDescriptor im Hauptthread verwenden (ich verwende es auch dazu) Änderungen an den Daten beobachten)?

Ich habe auch NSFetchedResultsController das Attribut, nach dem ich sortiere, aber das optimiert nur die Suche und nicht die Leistung.

Irgendwelche Ideen würden sehr geschätzt, danke!

    
monchote 14.04.2011, 09:43
quelle

6 Antworten

0

Zunächst wird NSFetchedResultsController normalerweise im Hauptthread verwendet. Und es unterstützt nicht Hintergrund holen bis jetzt Apple Release iOS 6.

Wenn Sie also den performFectch von NSFetchedResultController aufrufen, müssen Sie den Hauptthread eine Weile "blockieren". Wir möchten jedoch, dass die Zeit minimal ist.

(Soweit ich mich erinnern konnte, müssen Sie einen Sortierdeskriptor auf NSFetchedResultController setzen. Also bin ich mir nicht sicher, wie Sie es geschafft haben, ohne einen Sortierdeskriptor zu setzen. Schauen Sie sich die Klassenreferenz an)

Ich bin mir nicht sicher, ob Sie SQLite Store verwenden. Wenn dem so ist, kann ich Ihre Arbeit als Sortierer kaum glauben. (Werfen Sie einen Blick auf Core Data Programming Guide: Fehlersuche). Wenn nicht, halte so viele Daten im Speicher wäre keine gute Idee

Endlich haben wir den Punkt erreicht, warum es langsam ist. Diese Sortierung unter Verwendung von "localizedCaseInsensitiveCompare:" führt zu einem langsamen Abruf, da die Unicode-Zeichenfolge im Vergleich langsam ist. (erwähnt in WWDC 2010 Core Data Performance auf dem iPhone).

Wie viele andere Anwendungen sollten Sie ein Nicht-Unicode-String-Feld / -Eigenschaft basierend auf Ihrem "optionText" erstellen und basierend auf dieser Nicht-Unicode-String-Eigenschaft sortieren.

    
Bob Cromwell 17.11.2012, 13:50
quelle
3

Wie wäre es mit der batchSize -Eigenschaft von NSFetchRequest?

  

Wenn Sie eine Stapelgröße ungleich Null festlegen, wird die Auflistung der zurückgegebenen Objekte zurückgegeben   Wenn der Abruf ausgeführt wird, wird in Stapel aufgeteilt. Wenn das Holen ist   ausgeführt, wird die gesamte Anfrage ausgewertet und die Identitäten von allen   übereinstimmende Objekte, die aufgezeichnet wurden, aber nicht mehr als die Daten von batchSize-Objekten   wird zu einem bestimmten Zeitpunkt aus dem persistenten Geschäft geholt. Das Array   Von der Ausführung der Anfrage zurückgegeben wird ein Proxy-Objekt, das   Transparente Fehlchargen bei Bedarf. (In Datenbankbegriffen ist dies ein   In-Memory-Cursor.)

    
samvermette 13.09.2011 14:31
quelle
1

Ich führe einen Batch im Hintergrund in einer NSOperation aus, die einen separaten NSManagedObjectContext verwendet. In regelmäßigen Abständen speichere ich den zweiten Kontext, der eine Benachrichtigung auslöst, um meinen Haupt-NSManagedContext zu aktualisieren, an den mein NSFetchedResultsController angeschlossen ist.

Vielleicht könnte eine ähnliche Technik auf Ihren Abruf angewendet werden

Hier ist ein Kakao ist meine Freundin Artikel darüber:

Ссылка

und das Verfahren wird auch im Leitfaden für die Kerndatenprogrammierung "Importieren in Stapeln"

erwähnt

Ссылка

    
bandejapaisa 19.09.2011 16:26
quelle
0

Die Verwendung eines Caches würde wahrscheinlich zu einer besseren Leistung führen.

Ich habe das gleiche Problem und habe erkannt, dass der Abruf im ersten Aufruf mehr als 3 Sekunden benötigt, aber den Abruf zweimal durchführt, zeigt sofort seine Ergebnisse.

    
user689081 11.08.2011 09:42
quelle
0

Das Anzeigen von 6000 Zeilen in einer Tabelle ist möglicherweise nicht die beste Lösung für die Benutzererfahrung. Vielleicht solltest du vorher eine Filtertabelle hinzufügen. Ähnlich wie die Gruppen im Adressbuch. Dies würde möglicherweise zu einer besseren Benutzererfahrung führen, wenn Sie die Anzahl der Zeilen pro Filteroption auf eine handlichere Zahl reduzieren können. Dies würde Ladezeit und Scrollzeit reduzieren.

Ich weiß nicht, welche Art von Daten Sie anzeigen, daher gibt es vielleicht keine andere Möglichkeit, als alle in einer langen Liste anzuzeigen. Für Personen können Sie Optionen für Geschlecht und Altersgruppen hinzufügen. Für Autos können Sie einen Filter nach Marke und Modellen hinzufügen ....

    
FelixLam 11.08.2011 09:52
quelle
-4

Haben Sie versucht, die Methode performFetch: im Hintergrund auszuführen, entweder mit

%Vor%

oder

%Vor%     
casademora 14.05.2011 05:49
quelle