AFNetworking + NsOperationQueue - Laden Sie Tausende von Bildern herunter

8

Ich arbeite an einer Aufgabe (nur iOS5 +), bei der Tausende von Bildern vom Server heruntergeladen werden. Die Bilder gehören zu bestimmten Kategorien und jede Kategorie kann Hunderte von Bildern haben. Was ich tun muss, ist folgendes: -

1) Stellen Sie sicher, dass die App fehlende Bilder im Hintergrund herunterlädt, wenn die App aktiv ist (selbst wenn der Nutzer in anderen Bereichen der App sucht, die nicht mit Fotos zu tun haben).

2) Wenn der Benutzer auf eine Fotokategorie klickt, müssen die Bilder in dieser Kategorie mit hoher Priorität heruntergeladen werden, da diese sofort sichtbar sein müssen.

All dies tritt nur auf, wenn das Bild nicht bereits offline verfügbar ist. Sobald es heruntergeladen ist, wird das Bild aus dem lokalen Speicher verwendet.

Um das zu lösen, verwende ich folgende Logik: -

1) In AppDelegate.m, in applicationDidBecomeActive , fange ich an, fehlende Bilder herunterzuladen. Dazu führe ich eine Core Data-Abfrage durch, finde heraus, welche Bilder fehlen und fange an, sie in einem Thread mit BACKGROUND-Priorität herunterzuladen. So etwas wie: -

%Vor%

Der Code downloadMissingImages sieht folgendermaßen aus: -

%Vor%

Das funktioniert, aber es blockiert die Hauptbenutzeroberfläche und die App stürzt nach einer Weile ab. Dies ist, wenn ich versuche, ungefähr 700 Bilder herunterzuladen. Mit mehr Bildern würde es sicherlich abstürzen.

2) Wenn ein Benutzer auf eine Kategorie klickt, muss ich diese Bilder zuerst herunterladen, da sie dem Benutzer sofort angezeigt werden müssen. Ich bin mir nicht sicher, wie ich den Aufruf von missingImages unterbrechen kann und sage ihm, er solle bestimmte Bilder vor anderen herunterladen.

Im Grunde genommen muss ich also alle fehlenden Bilder im Hintergrund herunterladen, aber wenn der Benutzer die Fotokategorie durchsucht, müssen diese Bilder in der Download-Warteschlange hohe Priorität haben.

Ich weiß nicht, wie ich das effizient machen kann. Irgendwelche Gedanken?

Die Crash-Logs sehen so aus

%Vor%

Vielen Dank im Voraus.

    
Anuj Gakhar 24.06.2012, 07:49
quelle

1 Antwort

3

Über den Absturz denke ich, dass deine App aufgrund einer der beiden folgenden Optionen getötet wurde:

  1. Die App reagiert nicht mehr (und reagiert nicht mehr auf den iOS Sentinel-Prozess);

  2. zu viel Arbeitsspeicher, der in der Schleife verwendet wird, um über 700 Anforderungsoperationen zu erstellen.

Um zu klären, was wirklich passiert, sollten Sie mehr Informationen über den Absturz (das Konsolenprotokoll) bereitstellen. In jedem Fall würde die Lösung die Bilder in Chunks von vielleicht 10 oder 20 laden (Sie könnten sogar 1 zu 1 gehen, wenn Sie möchten, sehe ich nicht viel Problem damit).

Über den zweiten Punkt, was ist das:

  1. Laden Sie ein Bild mit höherer Priorität im Hauptthread herunter (natürlich über einen asynchronen Download, um ein Blockieren der Benutzeroberfläche zu vermeiden);

  2. Bevor Sie mit dem Download eines "Offline" -Bildes beginnen, prüfen Sie, ob das Bild bereits in der Zwischenzeit durch einen "höherpriorisierten" Download heruntergeladen wurde.

Um Punkt 2 gut zu behandeln, müssten Sie wahrscheinlich Ihre benutzerdefinierte Operation an Stelle von AFImageRequestOperation in die Warteschlange stellen, um die Überprüfung vor dem eigentlichen Download durchzuführen.

BEARBEITEN:

Beim Herunterladen von Bildern in Chunks können Sie mithilfe von Versandgruppen Ihre Netzwerkvorgänge gruppieren:

%Vor%

In diesem Beispiel verwende ich eine Dispatch-Gruppe, um eine Anzahl asynchroner Operationen zu gruppieren und darauf zu warten, dass sie alle ausgeführt werden. Wenn dispatch_group_wait zurückkehrt, können Sie eine weitere Runde ausführen (indem Sie Kerndaten abfragen und dann Ops versenden).

Über Ihre andere Frage (Wie überprüfe ich, ob eine Warteschlange mit höherer Priorität bereits ein bestimmtes Bild heruntergeladen hat), sollten Sie eine Core-Datenabfrage durchführen, bevor Sie jedes AFImageRequestOperation ausführen; Eine Möglichkeit besteht darin, eine eigene Klasse daraus abzuleiten und die Methode start zu überschreiben, um die Überprüfung durchzuführen.

In beiden Fällen könnten Sie die Logik viel vereinfachen, indem Sie die Bilder einzeln herunterladen (dh die for (...) -Schleife wäre nicht vorhanden; Sie fragen einfach das nächste Bild ab, um es herunterzuladen und herunterzuladen; vorher Herunterladen Sie überprüfen, es ist nicht schon da.

Ich würde vorschlagen, diesen einfacheren Weg zu gehen.

Ich hoffe, es hilft.

    
sergio 24.06.2012, 10:28
quelle