Frage

Ich erstelle eine iPhone-Anwendung, die Daten nach unten von einem Web-API ziehen, einschließlich E-Mail-Adressen. Ich mag ein Bild mit jeder E-Mail-Adresse in Tabellenzellen zugeordnet angezeigt werden, so dass ich das Adressbuch Suche nach Bildern und auf einem Standardzurückzufallen, wenn die E-Mail-Adresse nicht im Buch ist. Dies funktioniert gut, aber ich habe ein paar Bedenken:

  • Performance : Die Rezepte Ich habe für die Suche nach einer Adressbuch Aufzeichnung von E-Mail-Adresse (oder Telefonnummer) sind angeblich eher langsam . Der Grund dafür ist, dass man jeden Adreßbucheintrag iterieren muss, und für jeden, der ein Bild hat, Iterierte über alle E-Mail-Adressen eine Übereinstimmung zu finden. Dies kann zeitaufwendig für eine große Adressbuch sein, natürlich.

  • Tabellenzellen : Also ich dachte, dass ich alle E-Mail sammeln würde Adressen, für die ich brauche, Bilder zu finden und sie alle auf einmal zu finden. So kann ich durch das Buch iterieren nur einmal für alle Adressen. Aber das funktioniert nicht gut für Tabellenzellen, wobei jede Zelle entspricht eine einzige E-Mail-Adresse. Ich würde entweder alle die Bilder zu sammeln, bevor alle Zellen (möglicherweise langsam) angezeigt wird, oder jede Zelle Look jedes Bild haben, wie es Lasten (noch langsamer, als ich zu iterieren durch das Buch brauchen würde, um eine Übereinstimmung zu finden < em> jede E-Mail-Adresse ).

  • Asynchronous Lookup : Also dachte ich, ich sie in der Masse nach oben aussehen würde, aber asynchron, mit NSInvocationOperation . Für jedes Bild in Adressbuch gefunden, würde ich ein Miniaturbild in der App Sandbox speichern. Dann könnte jede Zelle nur diese Datei verweisen und den Standard zeigen, wenn sie nicht vorhanden sind (weil es nicht im Buch ist oder noch nicht gefunden wurde). Wenn das Bild später in der asynchronen Lookup, das nächste Mal das Bild angezeigt werden muss, gefunden wird, wäre es plötzlich erscheinen. Dies könnte auch für periodische Regeneration von Bildern arbeiten (wenn Bilder haben im Adressbuch, zum Beispiel geändert). Aber dann für jede gegebene Instanz von meiner app, kann ein Bild tatsächlich eine Zeit lang nicht angezeigt.

  • Asynchronous Tabelle Lookup Cell : Idealerweise würde ich so etwas wie verwenden markjnet der asynchronen Tabellenzelle Aktualisierung Update Tabellenzellen mit einem Bild, sobald es heruntergeladen wurde. Aber für diese Arbeit, würde ich habe einen NSInvocationOperation Job für jede Zelle ausgliedern, wie es angezeigt wird und wenn das zwischengespeicherte Symbol aus der Sandbox fehlt. Aber dann sind wir wieder zu ineffektiv für jede durch das gesamte Adressbuch Iterieren ein und dass viele von ihnen sein kann, wenn man gerade eine ganze Reihe von neuen E-Mail-Adressen heruntergeladen werden.

Meine Frage ist also: Wie andere das tun? Ich war mit Tweetie2 Hantieren, und es sieht aus wie es asynchron Tabellenzellen angezeigt aktualisiert. Ich nehme an, es ist für jedes Bild eine separate HTTP-Anforderung sendet er braucht. Wenn ja, dann stelle ich mir vor, dass die lokale Adressbuch per E-Mail-Adresse suchen ist nicht weniger effizient, so vielleicht ist das der beste Ansatz? Nur sich keine Sorgen um die Performance-Probleme im Zusammenhang mit dem Adressbuch suchen?

Wenn ja ist, ein Miniaturbild in der Sandbox-Caching den besten Ansatz zu speichern? Und wenn ich will, einen neuen Job erstellen, um alle Miniaturen mit allen Änderungen im Adressbuch sagt sich einmal täglich zu aktualisieren, was der beste Ansatz ist, dies zu tun?

Wie der Rest von euch, diese Art von Problem lösen? Vorschläge wäre sehr willkommen!

War es hilfreich?

Lösung

Unabhängig davon, welche Strategie Sie verwenden für die eigentliche Caching von Bildern, würde ich nur einen Durchlauf durch die Adressbuchdaten macht jedes Mal, wenn Sie einen Stapel von E-Mail-Adressen erhalten, wenn möglich. (Und ja, ich würde die asynchron tun.)

Eine NSMutableDictionary, die als In-Memory-Cache für Suchergebnisse dienen. Initialisieren dieses Wörterbuch mit jeder E-Mail-Adresse aus dem Download als Schlüssel, mit einem Sentinel als dass Schlüsselwert (wie [NSNull null]).

Als nächstes durchläuft jedes ABRecordRef im Adressbuch, Aufrufe ABRecordCopyValue(record, kABPersonEmailProperty) und Looping durch die Ergebnisse in jedem ABMultiValue, der zurückgegeben wird. Wenn eine der E-Mail-Adressen sind die Schlüssel in Ihrem Cache, Satz [NSNumber numberWithInt:ABRecordGetRecordId(record)] als der Wert dieses Schlüssels in Ihrem Wörterbuch.

Mit diesem Wörterbuch als Lookup-Index können Sie schnell die Bilder von ABRecordRefs erhalten nur für die E-Mail-Adressen, die Sie in Ihrer Tabellenansicht angezeigten den Benutzers aktuelle Scroll-Position gegeben, wie in hoopjones Antwort vorgeschlagen. Sie können ein Adressbuch Änderungsempfänger fügen Sie Ihre Cache ungültig zu machen, eine andere Indexierungsvorgang auslösen, und dann die Ansicht aktualisieren, wenn Ihre Anwendung das Niveau der „up-to-date-ness“ muss.

Andere Tipps

würde ich die letzte Methode verwenden Sie (Asynchronous Table Lookup Cell) aufgelistet, sondern nur Bilder sehen für die aktuellen Datensätze angezeigt werden. Ich überlastete die UIScrollViewDelegate Methoden, um herauszufinden, wenn ein Benutzer Scrollen gestoppt hat, und starten Sie dann nur Anfragen für die aktuellen sichtbaren Zellen zu machen.

So etwas wie dies (das leicht aus einem Tutorial modifiziert die ich im Internet gefunden, die ich jetzt nicht finden kann, Entschuldigungen für den Autor nicht zitiert):

- (void)loadContentForVisibleCells
{
    NSArray *cells = [self.table visibleCells];
    [cells retain];
    for (int i = 0; i < [cells count]; i++) 
    { 
        // Go through each cell in the array and call its loadContent method if it responds to it.
        AddressRecordTableCell *addressTableCell = (AddressRecordTableCell *)[[cells objectAtIndex: i] retain];
        [addressTableCell loadImage];
        [addressTableCell release];
        addressTableCell = nil;
    }
    [cells release];
}


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 
{
    // Method is called when the decelerating comes to a stop.
    // Pass visible cells to the cell loading function. If possible change 
    // scrollView to a pointer to your table cell to avoid compiler warnings
    [self loadContentForVisibleCells]; 
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    if (!decelerate) 
    {
       [self loadContentForVisibleCells]; 
    }
}

Sobald Sie wissen, was Adresse Aufzeichnungen zur Zeit sichtbar sind, nur die Suche für die (5 -7 Aufzeichnungen wahrscheinlich) wird blitzschnell sein. Sobald Sie das Bild greifen, nur um es Cache in einem Wörterbuch, so dass Sie müssen nicht später die Anforderung für das Bild wiederholen.

Sie scheinen zu versuchen, faul Bilder zu implementieren in UITableView zu laden. es ist ein gutes Beispiel von Apple, ich bin Referenzierung es hier: Lazy Load Bilder in UITableView

Zur Info, ich habe eine kostenlose, leistungsstarke veröffentlicht und einfache Bibliothek zu tun asynchronen Laden von Bildern und schnelle Datei-Caching: HJ Managed Objects http://www.markj.net/asynchronous-loading-caching- Bilder-iphone-hjobjman /

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top