2011-12-13 1 views
15

Il profiler orario mostra l'operazione che richiede più tempo nella mia app sta caricando UITableViewCells dai file pennino. Il più costoso dei quali prevede il caricamento di un UITableViewCell con un'immagine 4KB.È più veloce creare UITableViewCell a livello di codice o caricarne uno da un pennino?

sto caricando il UITableViewCell dal pennino con il seguente codice:

[[NSBundle mainBundle] loadNibNamed:@"UITableViewCellPortrait" owner:self options:NULL]; 
    cell = portraitCell; 
    self.portraitCell = nil; 

Qualcuno ha paragonato la differenza tra la creazione di una vista a livello di codice o il caricamento di un UITableViewCell da un pennino?

MODIFICA:
Ho confrontato il profilo temporale delle ripetute corse di caricamento del UITableViewCell da un pennino e la creazione della vista a livello di programmazione. Il mio test ha coinvolto alternativamente tra due UITableViews circa 10 volte nell'arco di 3-5 secondi. In ciascun test, il caricamento dello UITableViewCell a livello di codice era sostanzialmente più veloce, da 2 a 6 volte più veloce.

Qualcuno può confermare questi risultati?

EDIT: Ho aggiornato il codice di nasello di carico per caricare solo il file pennino in una volta e utilizza una versione in cache per le chiamate successive.

if (self.UITableViewPortaitNib == nil) { 
     self.UITableViewPortaitNib = [UINib nibWithNibName:@"UITableViewCellPortrait" bundle:[NSBundle mainBundle]]; 
    } 

    self.UITableViewPortaitNib instantiateWithOwner:self options:NULL]; 
    cell = portraitCell; 
    self.portraitCell = nil; 

Ho anche utilizzato lo strumento di automazione per creare piste più coerenti ed i risultati suggeriscono ancora carico UITableViewCells di programmazione è più veloce di caricare UITableViewCells per un pennino. Il tempo medio di esecuzione del caricamento di UITableViewCells da un pennino era di circa 90 ms, mentre la durata media della creazione di UITableViewCell a livello di programmazione era di 50 ms.

+0

Mostraci il codice di caricamento del pennino. –

+0

Grazie per dare un'occhiata @robmayoff. Ho aggiornato la domanda per includere il mio codice per caricare il pennino. – Eytan

+0

Scoperta interessante: potresti eseguire nuovamente l'esperimento utilizzando storyboard e celle prototipo, in cui la vista tabella esegue il caricamento di tutto il pennino in background? – jrturton

risposta

13

Provare a creare un oggetto UINib una volta e quindi inviarlo instantiateWithOwner:options: ogni volta che è necessario creare una nuova cella. Dal UINib Class Reference:

Ad esempio, se la visualizzazione della tabella utilizza un file pennino per creare un'istanza di vista tavolo cellule, la memorizzazione nella cache il pennino in un oggetto UINib in grado di fornire un significativo miglioramento delle prestazioni.

+0

Wow che ha aiutato molto! Il tempo medio di esecuzione (per la durata dei teisti) è sceso da circa 300ms a 90ms durante il caricamento da NIB usando la tecnica che hai citato. Caricamento in modo programmatico, ha avuto un tempo di esecuzione medio di circa 50 ms. – Eytan

2

carico la cella di pennino (cellTemplate) una volta duplicato come necessario, quindi in un certo senso questo approccio è programmatico e pennino base.

La duplicazione è stata più complicata di quanto mi aspettassi poiché mutableCopy non ha funzionato. Un NSKeyedArchiver andata e ritorno fatto, però:

NSData* cellData = [NSKeyedArchiver archivedDataWithRootObject:cellTemplate]; 
cell = [NSKeyedUnarchiver unarchiveObjectWithData:cellData]; 

In realtà se si sta andando a crudo, fiammeggiante, pedal-to-the-speed metal, anche il modello archiviato può essere calcolata una volta e memorizzata nella cache.

Ma non dovresti misurare il frame rate? In tal caso, anche la complessità di UIView entra in gioco.

+0

Ho intenzione di provare il metodo di archiviazione con chiave domani mattina. Si tocca un punto buono per quanto riguarda il frame rate. Il motivo per cui ho iniziato ad analizzare il metodo più veloce per UITableViewCells è perché la mia animazione di modifica dell'orientamento è estremamente lenta. Durante questa animazione, la transizione tra due UITableViewControllers e il profiler del tempo evidenziato evidenzia la traccia dello stack più pesante quando carico UITableViewCells. Hai qualche suggerimento su come accelerare il frame rate? – Eytan

0

È possibile riutilizzare i pennini uitableviewcell che vengono caricati una volta e che quindi escono dalla visualizzazione.Leggi il seguente:

iPhone - What are reuseIdentifiers (UITableViewCell)?

+0

Hai un buon punto Sanjay. Alcune righe sopra il codice di caricamento del pennino, controllo le celle con l'identificativo di riutilizzo appropriato. – Eytan

5

In iOS 5 e di cui il WWDC 2011 video, c'è un metodo più recente che utilizza UINib. Si registra il pennino nel metodo viewDidLoad: e quindi si semplifica il codice nel metodo tableView:cellForRowAtIndexPath:. Questo potrebbe velocizzare le cose per te (ma non ho mai eseguito un confronto temporale).

Esempio: Nella tua viewDidLoad: registrare il pennino e mantenere un riferimento ad esso:

NSString *myIdentifier = @"ReusableCustomCell"; 
[self.reuseCustomCell registerNib:[UINib nibWithNibName:@"ReusableCustomCell" bundle:nil] forCellReuseIdentifier:myIdentifier]; 

nel metodo tableView:cellForRowAtIndexPath: basta chiedere per la cella (non c'è bisogno di verificare la presenza di nullo, perché è garantito per restituire un cella sotto iOS5) e configurare la cella:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *myIdentifier = @"ReusableCustomCell"; 

    ReusableCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:myIdentifier]; 
    // Your configuration code goes here 
    cell.nameLabel.text = @"some text"; 
    // .... 

    return cell; 
} 

Codice non testato. Sarei interessato se fosse più veloce di usare UINib da solo.

+0

Questo è essenzialmente la stessa cosa che usare un Uinib come sono nella mia seconda modifica. Non riesco a immaginare che sarebbe più veloce ma sicuramente è più bello da programmare. Lo farò d'ora in poi - Grazie! – Eytan

+0

a cosa si riferisce "self.reuseCustomCell"? – zakdances

+0

self.reuseCustomCell è una proprietà sulla falsariga di @property (nonatomic, strong) id reuseCustomCell; –