tldr: ImagedNamed va bene. Gestisce bene la memoria. Usalo e smettila di preoccuparti.
Modifica Nov 2012: nota che questa domanda risale a iOS 2.0! I requisiti e la gestione delle immagini sono passati molto da allora. Retina rende le immagini più grandi e caricandole leggermente più complesse. Con il supporto integrato per le immagini iPad e retina, dovresti sicuramente usare ImageNamed nel tuo codice. Ora, per i posteri:
Lo sister thread sui forum Apple Dev ha ricevuto un traffico migliore. Nello specifico, Rincewind ha aggiunto un po 'di autorità.
Ci sono problemi in iPhone OS 2.x in cui imageNamed: cache non viene cancellato, anche dopo un avviso di memoria. Allo stesso tempo + imageNamed: ha ottenuto un sacco di utilizzo non per la cache, ma per la comodità, che ha probabilmente ingrandito il problema più di quanto avrebbe dovuto essere.
pur avvertendo che
Sul fronte velocità, c'è un malinteso generale di ciò che sta accadendo. La cosa più grande che + imageNamed: fa è decodificare i dati dell'immagine dal file sorgente, che gonfia quasi sempre in modo significativo la dimensione dei dati (ad esempio, un file PNG di dimensioni dello schermo potrebbe consumare poche decine di KB quando compresso, ma consuma più di mezzo MB decompresso - larghezza * altezza * 4). Al contrario + imageWithContentsOfFile: decomprimerà quell'immagine ogni volta che saranno necessari i dati dell'immagine. Come puoi immaginare, se hai bisogno dei dati dell'immagine solo una volta, non hai vinto nulla qui, tranne che per avere una versione cache dell'immagine che gira intorno, e probabilmente più a lungo del necessario. Tuttavia, se si dispone di un'immagine grande che è necessario ridisegnare spesso, allora ci sono alternative, anche se quella che raccomanderei principalmente è di evitare di ridisegnare quella grande immagine :).
Rispetto al comportamento generale della cache, fa cache in base al nome file (quindi due istanze di + imageNamed: con lo stesso nome dovrebbe comportare riferimenti agli stessi dati memorizzati nella cache) e la cache crescerà dinamicamente come richiedere più immagini tramite + imageNamed :. Su iPhone OS 2.x un bug impedisce che la cache venga ridotta quando viene ricevuto un avviso di memoria.
e
mia comprensione è che il + imageNamed: cache deve rispettare avvisi di memoria su iPhone OS 3.0. Provalo quando ne hai la possibilità e segnala bug se trovi che questo non è il caso.
Quindi, ce l'hai. imageNamed: non distruggerà le finestre o ucciderà i tuoi figli. È piuttosto semplice ma è uno strumento di ottimizzazione. Purtroppo è mal chiamato e non c'è equivaluent che è facile da usare - da qui la gente uso eccessivo e si arrabbiano quando lo fa semplicemente il suo lavoro
ho aggiunto una categoria per UIImage per risolvere questo:
// header omitted
// Before you waste time editing this, please remember that a semi colon at the end of a method definition is valid and a matter of style.
+ (UIImage*)imageFromMainBundleFile:(NSString*)aFileName; {
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", bundlePath,aFileName]];
}
Scuotewind ha anche incluso alcuni esempi di codice per creare la tua versione ottimizzata. Non riesco a vederlo vale la maintentace, ma qui è per completezza.
CGImageRef originalImage = uiImage.CGImage;
CFDataRef imageData = CGDataProviderCopyData(
CGImageGetDataProvider(originalImage));
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
CFRelease(imageData);
CGImageRef image = CGImageCreate(
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
CGImageGetBitsPerComponent(originalImage),
CGImageGetBitsPerPixel(originalImage),
CGImageGetBytesPerRow(originalImage),
CGImageGetColorSpace(originalImage),
CGImageGetBitmapInfo(originalImage),
imageDataProvider,
CGImageGetDecode(originalImage),
CGImageGetShouldInterpolate(originalImage),
CGImageGetRenderingIntent(originalImage));
CGDataProviderRelease(imageDataProvider);
UIImage *decompressedImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
Il compromesso con questo codice è che l'immagine decodificata utilizza più memoria ma il rendering è più veloce.
Sono pieno di suspense. :) – Kriem
anch'io. Sembra che SO non sia così pieno di geni come pensavo. –
Sembra che tu abbia passato un po 'di tempo a indagare su questo. Hai fatto qualche esperimento che mostrasse qualsiasi impatto negativo di UIImage imageNamed con l'ultima versione di cacao-touch? Creare un UITableView e aggiungere un sacco (molte migliaia) di righe e vedere se il rendimento va giù quando si mostra un'immagine diversa in ogni riga. Forse allora le persone possono commentare le tue scoperte. – stefanB