Schlechte UICollectionView-Scrolling-Performance Mit UIImage
Ich habe eine UICollectionView in meiner app, und jede Zelle ist ein UIImageView und einige Beschriftungen. Das problem ist, dass wenn ich die UIImageViews zeigen Ihre Bilder, die Scroll-performance ist schrecklich. Es ist nirgendwo nahe so glatt wie das scrolling Erfahrung einer UITableView oder sogar die gleichen UICollectionView, ohne die UIImageView.
Fand ich diese Frage von vor ein paar Monaten, und es scheint wie eine Antwort gefunden wurde, sondern es ist geschrieben in RubyMotion, und das habe ich nicht verstanden. Ich habe versucht, um zu sehen, wie es zu konvertieren, um Xcode, da ich aber noch nie benutzt NSCache entweder, es ist ein wenig schwer zu. Das poster ist auch darauf zu hier über die Implementierung etwas zusätzlich zu Ihrer Lösung, aber ich bin nicht sicher, wo zu setzen, dass der code entweder. Vielleicht, weil ich nicht verstehen, den code aus dem erste Frage.
Wäre jemand in der Lage zu helfen, übersetzen diese in Xcode?
def viewDidLoad
...
@images_cache = NSCache.alloc.init
@image_loading_queue = NSOperationQueue.alloc.init
@image_loading_queue.maxConcurrentOperationCount = 3
...
end
def collectionView(collection_view, cellForItemAtIndexPath: index_path)
cell = collection_view.dequeueReusableCellWithReuseIdentifier(CELL_IDENTIFIER, forIndexPath: index_path)
image_path = @image_paths[index_path.row]
if cached_image = @images_cache.objectForKey(image_path)
cell.image = cached_image
else
@operation = NSBlockOperation.blockOperationWithBlock lambda {
@image = UIImage.imageWithContentsOfFile(image_path)
Dispatch::Queue.main.async do
return unless collectionView.indexPathsForVisibleItems.containsObject(index_path)
@images_cache.setObject(@image, forKey: image_path)
cell = collectionView.cellForItemAtIndexPath(index_path)
cell.image = @image
end
}
@image_loading_queue.addOperation(@operation)
end
end
Hier ist der code aus der zweite Frage, dass der Fragesteller von der erste Frage gesagt das problem gelöst:
UIImage *productImage = [[UIImage alloc] initWithContentsOfFile:path];
CGSize imageSize = productImage.size;
UIGraphicsBeginImageContext(imageSize);
[productImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
productImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Wieder, ich bin mir nicht sicher, wie/wo und zu implementieren.
Vielen Dank.
- Veröffentlichen Sie Ihren code! Was haben Sie versucht? Warum ist die Leistung Ihrer app so langsam? Was ist das Ergebnis von profiling, um zu sehen, was Los ist???
- Es ist nicht meine gesamte app ist langsam, es ist nur einen Bildlauf durch die Zellen in der UICollectionView. Der rest der app funktioniert sehr gut. Ich bin derzeit mit
cell.cardImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:tempCard]];
um das Bild. Das Bild(s) verwendet wird, ist nicht Teil des app-bundle, sondern in der Regel heruntergeladen und gespeichert in dem Cache-Ordner.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist das Muster, das ich Folgen. Laden Sie immer asynch und cache das Ergebnis. Machen Sie keine Annahme über den Zustand der Ansicht, wenn der asynch Ladevorgang abgeschlossen ist. Ich habe eine Klasse, die vereinfacht die Lasten wie folgt:
Nun die Zelle (Auflistung oder Tabelle) update ist ziemlich einfach:
url
immernil
. Irgendwelche Gedanken?NSURL
auf den app-store vor Ort.url
zu null. Ich war mit ein Pfad statt url. Im wesentlichen, die mir fehlte, diefile://
Teil der Zeichenfolge. Ich bin jetzt in der Lage, um die vollständige URL, die generiert wird, aber es ist immer noch nicht geladen, das Bild. Wenn ich die URL in Safari auf meinem computer, lädt es das Bild perfekt, so weiß ich, dass die URL gültig ist. Jedoch, laden Sie das Bild von meinem server und nicht lokal funktioniert, und das scrollen ist erstaunlich glatt. Indem Sie die folgenden Schritte aus, sowohl lokale als auch remote-URLs, die sich ähnlich Verhalten, so bin ich nicht sicher, wo das Problem ist.Cache.db
- Datei. Es scheint, dass es tut halten eine lokale Kopie des Bildes irgendwo, weil nach dem ausführen der app einmal, es ging nie zurück- (void)startWithCompletion:(void (^)(UIImage *, NSError *))completion
UICollectionView
Schriftrollen so reibungslos mit den Bildern funktioniert es ohne. Vielen, vielen Dank!if (image) return completion(image, nil);
. Die Linie gibt einenblock
innerhalb einesvoid
Methode, was ist also derblock
zurück?Im Allgemeinen schlecht scrolling-Verhalten für UICollectionViews oder UITableViews geschieht, weil die Zellen werden aus der Warteschlange entfernt und gebaut in den Haupt-thread von iOS. Es gibt wenig Freiheit, um zu precache-Zellen oder bauen Sie in einem hintergrund-thread, statt Sie aus der Warteschlange entfernt und gebaut, da Sie einen Bildlauf Blockierung der Benutzeroberfläche. (Ich persönlich finde, dass schlechtes design von Apple obwohl es nicht der Einfachheit halber, weil Sie nicht haben, um sich bewusst sein über mögliche threading Probleme. Ich denke, Sie sollte ein Haken, obwohl, um eine benutzerdefinierte Implementierung für eine UICollectionViewCell/UITableViewCell pool, die mit dem entfernen/wiederverwenden von Zellen).
Den wichtigsten Ursachen für den Leistungsabfall sind in der Tat im Zusammenhang mit Bild-Daten und (in Abnehmender Größenordnung) sind meiner Erfahrung:
Da bin ich sehr wählerisch, smooth-scrolling (auch wenn es nur das erste mal, wenn eine Zelle verwendet wird) konstruierte ich eine ganze framework zu precache-Zellen, indem bilden von Unterklassen UINib (dies ist im Grunde der einzige Haken erhalten Sie in der abarbeiten der Warteschlange Prozess von iOS). Aber das ist vielleicht über Ihre Bedürfnisse.
Ich hatte Fragen über
UICollectionView
scrollen.Was funktioniert (fast) wie ein Charme für mich: ich aufgefüllt, die Zellen mit png-thumbnails 90x90. Ich sage fast, denn die erste vollständige schriftrolle ist nicht so glatt, aber noch nie abgestürzt ist nicht mehr.
In meinem Fall, die Größe der Zellen ist 90x90.
Hatte ich viele original-png-Größen vor, und es war sehr abgehackt beim png-original Größe war größer als ~1000x1000 (viele Abstürze auf den ersten Blättern).
So, ich wähle 90x90 (oder ähnliches) auf die
UICollectionView
und Anzeige die original png ' s (unabhängig von der Größe). hoffe, es kann anderen helfen.