Das Laden des Bildes von CoreData bei cellForRowAtIndexPath verlangsamt das Scrollen

8

Ich arbeite an einer UITableView, die der iOS-App für Fotos sehr ähnlich ist: Sie enthält viele Zeilen mit jeweils 4 Miniaturansichten in jeder Zeile. (d. h. jede UITableViewCell hat 4 UIImageViews) Alle Thumbnails werden aus den Core Data geladen.

Ich habe meine Implementierung mehrfach überarbeitet und kann Leistungsverbesserungen sehen, es ist jedoch immer noch nicht in der Lage, so glatt wie die Foto-App zu scrollen.

Ich muss beraten, wie die Fotos für die beste Leistung richtig zwischengespeichert werden. Das habe ich versucht:

1. Mein erster Versuch (extreme Verzögerung beim Scrollen)

  • Bilder werden mit dem in CoreData transformierbaren Typ gespeichert.
  • In der Funktion cellForRow wird jedes Bild von CoreData auf der flieg.

2. Zweiter Versuch (schneller, aber beim Scrollen ein wenig nacheilen)

  • Bilder werden mit dem Typ Binary Data gespeichert, wobei die Option 'external storage' in CoreData aktiviert ist.
  • In der cellForRow-Funktion wird jedes Bild zuerst aus den Core Data geladen und dann im Speicher in NSCache gespeichert, damit wir nächstes Mal, wenn cellForRow ausgelöst wird, das UIImage von NSCache direkt verwenden, falls verfügbar.

Nach dem Verwenden von NSCache zum Zwischenspeichern von Bildern, die von CoreData geladen wurden, ist das Scrollen sichtbar schneller, aber da Bilder immer noch von CoreData geladen werden müssen, wenn sie in NSCache noch nicht verfügbar sind, wird das Scrollen von Zeit zu Zeit ruckartig sein.

Also, es muss einen besseren Weg geben, ich könnte alle Bilder in den Speicher laden, aber da es eine große Anzahl oder Reihen von Bildern geben könnte, wollte ich die Bilder überhaupt nicht laden.

Was kann ich noch tun, um das Bild in CellForRowAtIndexPath schneller zu laden?

    
mkto 31.01.2013, 10:34
quelle

3 Antworten

25

Damit das Scrollen unabhängig davon, woher Ihre Daten stammen, reibungslos abläuft, müssen Sie Ihre Daten in einem separaten Thread abrufen und die Benutzeroberfläche nur aktualisieren, wenn sich die Daten im Speicher befinden. Grand Central Despatch ist der richtige Weg. Hier ist ein Skelett, das davon ausgeht, dass Sie ein self.photos Wörterbuch mit einer Textreferenz auf eine Bilddatei haben. Das Bildminiaturbild kann in ein Live-Wörterbuch geladen werden oder nicht; kann oder darf nicht in einem Dateisystemcache sein; ansonsten wird aus einem Online-Shop geholt. Es könnte Core Data verwenden, aber der Schlüssel zum reibungslosen Scrollen ist, dass Sie nicht auf die Daten warten, egal wo sie herkommt.

%Vor%

Wenn Sie eine Art Einzelspeicher-Image-Store-Manager verwenden, erwarten Sie, dass der Manager die Details des Cache- / Datenbankzugriffs behandelt, was dieses Beispiel vereinfacht.

Dieser Teil

%Vor%

würde durch etwas wie

ersetzt werden %Vor%

(Sie würden keinen Abschlussblock verwenden, da Sie in GCD tatsächlich einen bereitstellen, wenn Sie in die Hauptwarteschlange zurückkehren)

    
foundry 31.01.2013, 11:40
quelle
0

Ich habe eine Klasse namens JMImageCache verwendet, um das Image auf Festplatte zwischenzuspeichern und dann nur die lokale URL (und die Remote-URL) zu speichern wenn Sie möchten) in CoreData. Sie können auch ein Thumbnail erstellen, das Sie auch auf dem Datenträger speichern, und die Thumbnail-URL zusammen mit der Bild-URL in den Stammdaten speichern und das Thumbnail in der Tabellenansicht verwenden.

    
Andrew Tetlaw 31.01.2013 11:34
quelle
0

Fügen Sie eine Unterklasse von NSValueTransformer für das Bild in den Kerndaten hinzu,

Code wie folgt:

%Vor%     
Suric 02.11.2015 07:05
quelle

Tags und Links