Domanda

Sto creando un'applicazione per iPhone che tirerà i dati giù da un API Web, inclusi gli indirizzi e-mail. Mi piacerebbe per visualizzare un'immagine associata a ciascun indirizzo di posta elettronica nelle celle di tabella, quindi sono alla ricerca di immagini la Rubrica e ricadere su un default se l'indirizzo di posta elettronica non è nel libro. Questa grande opera, ma ho alcune preoccupazioni:

  • Performance : Le ricette che ho trovato per la ricerca di un record di rubrica indirizzi per indirizzo e-mail (o numero di telefono) sono riferito piuttosto lento . La ragione di questo è che si deve iterare su ogni indirizzo libretto, e per ognuno che ha un'immagine, iterare su tutti gli indirizzi email per trovare una corrispondenza. Questo può richiedere molto tempo per un grande libro di indirizzo, naturalmente.

  • Celle Tabella : Così ho pensato di raccogliere tutti gli indirizzi email per cui ho bisogno di trovare le immagini e trovare tutti in una volta. In questo modo ho scorrere il libro solo una volta per tutti gli indirizzi. Ma questo non funziona bene per le celle della tabella, in cui ogni cella corrisponde a un unico indirizzo di posta elettronica. Mi piacerebbe sia necessario raccogliere tutte le immagini prima di visualizzare tutte le cellule (potenzialmente lento), o di avere ogni cella cercare ogni immagine come viene caricato (anche più lento, come avevo bisogno di scorrere il libro per trovare una corrispondenza per < em> ogni indirizzo e-mail ).

  • Asynchronous Lookup : Allora ho pensato che li avrei lo sguardo alla rinfusa, ma in modo asincrono, utilizzando NSInvocationOperation . Per ogni immagine trovata in rubrica, mi piacerebbe risparmiare una miniatura nella sandbox app. Poi ogni cella potrebbe solo riferimento a questo file e mostrare il default se non esiste (perché non è nel libro o non è stato ancora trovato). Se l'immagine è poi trovato nella ricerca asincrona, la prossima volta che l'immagine deve essere visualizzata sembrerebbe improvvisamente. Questo potrebbe funzionare bene per la rigenerazione periodica di immagini (per quando le immagini sono state modificate nella rubrica, per esempio). Ma poi per ogni istanza di mia app, un'immagine non può effettivamente presentarsi per un po '.

  • Tabella Asynchronous cellulare di ricerca : Idealmente, mi piacerebbe usare qualcosa come di markjnet asincrono cella di una tabella di aggiornamento per aggiornare celle della tabella con un'immagine una volta che è stato scaricato. Ma per far funzionare tutto questo, avrei dovuto scorporare un lavoro NSInvocationOperation per ogni cella come è visualizzato e se l'icona nella cache non è presente nella sandbox. Ma poi siamo tornati al iterazione inefficiente attraverso l'intera rubrica per ognuno, e che può essere un sacco di loro, se avete appena scaricato un sacco di nuovi indirizzi di posta elettronica.

Quindi la mia domanda è: come fanno gli altri questo? Mi stava armeggiando con Tweetie2, e sembra che aggiorna le celle di tabella visualizzati in modo asincrono. Presumo è l'invio di una richiesta HTTP separata per ogni immagine di cui ha bisogno. Se è così, immagino che la ricerca della rubrica locale per indirizzo e-mail non è meno efficiente, quindi forse questo è l'approccio migliore? Solo che non preoccuparsi dei problemi di prestazioni associati con la ricerca nella rubrica?

Se è così, sta salvando un'immagine in miniatura nella sandbox l'approccio migliore per la memorizzazione nella cache? E se volessi creare un nuovo lavoro per aggiornare tutte le miniature con le eventuali modifiche in rubrica dicono una volta al giorno, qual è l'approccio migliore per farlo?

Come il resto di voi a risolvere questo tipo di problema? Suggerimenti sarebbe molto apprezzato!

È stato utile?

Soluzione

Indipendentemente da quale strategia si utilizza per la memorizzazione nella cache effettivo di immagini, vorrei fare solo passaggio attraverso i dati della rubrica ogni volta che si ottiene una serie di indirizzi e-mail, se possibile. (E sì, vorrei farlo in modo asincrono.)

Crea un NSMutableDictionary che servirà come la cache in memoria per i risultati di ricerca. Inizializzare questo dizionario con l'indirizzo di posta elettronica dal download come una chiave, con una sentinella, come valore della chiave (come [NSNull null]).

Avanti, Sperimenta ogni ABRecordRef nella Rubrica, chiamando ABRecordCopyValue(record, kABPersonEmailProperty) e loop attraverso i risultati in ogni ABMultiValue che viene restituito. Se uno degli indirizzi e-mail sono le chiavi nella cache, impostare [NSNumber numberWithInt:ABRecordGetRecordId(record)] come il valore di quella chiave nel dizionario.

Utilizzando questo dizionario come un indice di ricerca, è possibile ottenere rapidamente le immagini di ABRecordRefs solo per gli indirizzi email che si sta visualizzando in vostra tabella visualizzazione data posizione di scorrimento corrente dell'utente, come suggerito nella risposta di hoopjones. È possibile aggiungere un indirizzo cambiamento libro ascoltatore per invalidare la cache, innescare un'altra operazione di indicizzazione e quindi aggiornare la vista, se l'applicazione ha bisogno di quel livello di "up-to-date-ness".

Altri suggerimenti

userei l'ultimo metodo che avete elencato (Asynchronous Tabella cellulare di ricerca), ma vedo solo le immagini per i record attuali di essere visualizzati. I metodi di sovraccaricare l'UIScrollViewDelegate per scoprire quando un utente ha smesso di scorrere, e poi iniziare a fare solo le richieste per gli attuali celle visibili.

Qualcosa di simile (questo è leggermente modificato da un tutorial che ho trovato sul web, che non riesco a trovare ora, scuse per non citare l'autore):

- (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]; 
    }
}

Una volta che sai cosa record indirizzo sono attualmente visibili, solo facendo una ricerca per coloro (5 -7 record probabilmente) sarà estremamente veloce. Una volta che si afferra l'immagine, basta memorizzare nella cache in un dizionario in modo che non c'è bisogno di rifare la richiesta per l'immagine successiva.

Ti sembra di cercare di attuare le immagini caricamento pigro in UITableView. c'è un buon esempio da parte di Apple, sto riferimento qui: pigri in UITableView

Cordiali saluti, ho pubblicato una libreria libera, potente e facile per fare asincrona loading image e caching veloce file: HJ Managed Objects http://www.markj.net/asynchronous-loading-caching- immagini-iphone-hjobjman /

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top