2012-10-18 8 views
19

Ho riscontrato un problema molto strano e mi chiedevo se qualcuno potesse aiutarmi qui da quando sono completamente perso.Problema di prestazioni di auto-download per iOS in modalità verticale. [NSISEngine ottimizza]

Contesto: Sto sviluppando un'applicazione con una gerarchia relativamente semplice. Solo pochi controller di visualizzazione ma un bel po 'di immagini ad alta risoluzione. Sono presentati in un UIScrollView con un po 'di testo, ecc. Durante il test in modalità verticale, la panoramica non scorreva affatto. Sembrava che il framerate fosse sceso a circa 4-5 fps. Per prima cosa ho pensato che fosse a causa delle immagini ad alta risoluzione.

Ma poi ho trasformato l'iPad in modalità orizzontale e tutto è andato liscio. Dal momento che ho un file xib separato per verticale e orizzontale, ho pensato che ci fosse un problema nel portrait-xib. Si è scoperto, non c'era. Entrambi avevano la stessa classe VC e quindi utilizzavano lo stesso codice e entrambi gli xib erano quasi identici tranne che per le dimensioni e le posizioni delle viste.

Per limitare il problema, ho utilizzato lo strumento TimeProfiler per vedere che cosa ha causato il problema. Come si è scoperto, TimeProfiler ha mostrato alcune chiamate a [NSISEngine optimize] (attivato da NSLayoutConstraint). In modalità verticale c'erano più chiamate e quelle chiamate richiedevano molto più tempo. Più in basso nell'albero l'ho visto in modalità ritratto [NSISEngine optimize] chiamato [NSISEngine fixupIntegralizationViolations] e in orizzontale no.

Ho persino rimosso tutti i viewcontroller dall'app tranne rootVC e uno altro presentato da rootVC. Il vc presentato contiene solo alcune immagini, pulsanti e alcune animazioni. Ha solo uno xib per entrambi gli orientamenti ed è (come tutti gli altri) disposto con l'autolayout.

Il layout funziona come dovrebbe in entrambi gli orientamenti e non ci sono ambiguità (per quanto posso dire, almeno po [[UIWindow keyWindow] _autolayoutTrace] non ne mostra nessuno).

Ho allegato uno screenshot del TimeProfile del processo di presentazione del vc. Uno per il ritratto e uno per il paesaggio. Come puoi vedere, in orizzontale le chiamate a [NSISEngine optimize] richiedono solo un millisecondo mentre in verticale superano i 3000 ms.

C'è qualcuno che può dirmi perché? O forse ha qualche idea su cosa posso fare per scoprire qual è il problema?

Qualsiasi aiuto sarebbe molto apprezzato!

Thx

Link a una versione più grande dell'immagine: link

Instruments Timeprofiler screenshot

risposta

3

Ho presentato una richiesta di supporto tecnico per quanto riguarda questo problema e, infine, ha ottenuto la risposta, che è più probabile un bug. La segnalazione di bug è archiviata. Spero che risolveranno presto. Se ci sono novità aggiornerò questa risposta.

+0

solo curioso di sapere se hai mai avuto un follow-up con questo bug report? Ho avuto problemi simili con strani ritardi di autolayout, con strumenti che mostravano molte chiamate a NSISEngine fixUpIntegralizationViolations ... –

+0

No, purtroppo non ho ancora sentito nulla – Tobi

4

Mi sono imbattuto nello stesso problema con una visualizzazione moderatamente complessa in cui si comportava bene su iPad non Retina o Retina iPad in modalità verticale. In modalità orizzontale su un dispositivo Retina ci sono voluti 10 volte di più per visualizzare un popover o spingere un'altra vista sullo stack di visualizzazione. Ho finito per sostituire il file XIB con un loadView codificato a mano nel controller di visualizzazione. Sembra che abbia eliminato il problema. Generatore di interfacce ha la tendenza a creare vincoli eccessivi, quindi controllarlo è la chiave per ottenere buone prestazioni di layout automatico.

Ho anche aperto un ticket di supporto per questo problema.

Aggiornamento:

ho trovato la causa della mia situazione. È stato il seguente insieme di vincoli:

NSArray *constraints = [NSLayoutConstraint 
         constraintsWithVisualFormat : @"|[sunLabel][monLabel(==sunLabel)][tueLabel(==sunLabel)][wedLabel(==sunLabel)][thuLabel(==sunLabel)][friLabel(==sunLabel)][satLabel(==sunLabel)]|" 
         options : 0 
         metrics : nil 
         views : labelViewsDictionary]; 

Si precisa che 7 etichette in una vista primaria usano le stesse dimensioni e tutte estendono la larghezza della vista primaria. Credo che l'eccessiva natura relazionale del layout stava dando adattamenti al layout automatico, soprattutto perché la larghezza della vista genitore non era equamente divisibile per 7.

Per risolvere il problema, ho creato una serie di vincoli che specificavano la larghezza di ciascuna etichetta e applicato quei vincoli. Quando il dispositivo ruota la larghezza del genitore cambia così torno indietro e aggiusto la costante sui vincoli per essere 1/7 della larghezza della vista genitore. Questo ora funziona bene, il processo di caricamento di un popover ora richiede meno di 300 ms anziché 2000ms.

0

Ho avuto lo stesso problema ieri in un dispositivo Ipad iOS6.1. La strumentazione dell'app ha rilevato che il metodo fixupIntegralizationViolations richiedeva circa 300 ms ogni volta che veniva chiamato (circa 20 volte, il che è molto) rendendo l'app assolutamente inutile.

Il mio problema era molto simile a quello dei commenti di Jack Cox, ma l'ho risolto in modo diverso. Il mio vincolo era:

@ "H: | [allButton] [inStoreButton (== allButton)] [onlineButton (== allButton)] [sortButton (50)] |"

Il problema è che il parentView qui è l'intera larghezza del paesaggio dell'iPad, quindi la matematica di questo contraint stava dando a ciascun pulsante questa larghezza: (1024-50)/3 = 324,6666667.

Questo in genere non è un problema in esecuzione automatica poiché si occupa di numeri float grandi e arrotondandoli correttamente, ma sembra che in iPad iOS6 l'arrotondamento orizzontale di questo numero innesca un bug che blocca l'interfaccia utente. Per andare in giro tutto ciò che dovevo fare è cambiare l'ordinamento con 52, quindi ogni larghezza del bottone ora è: (1024-52)/3 = 324. Questo è tutto. Ora il metodo fixupIntegralizationViolations richiede circa 1ms ogni volta che viene chiamato.

La cosa interessante è che l'utilizzo di 52 dà una larghezza non decimale in Orizzontale, ma fornisce un numero decimale in verticale: (768-52)/3 = 238,666667. Tuttavia, il ritratto sembra non avere alcun bug e l'autolayout arrotonda correttamente i numeri.

Problemi correlati