2012-06-06 10 views
6

Ho scritto un'enorme app per iPad 2 anni fa e ora sto tornando ad aggiornarlo su iOS5. È un po 'disordinato perché è stata la mia prima grande app per iPad.suggerimenti per rintracciare un'interfaccia utente iOS a congelamento intermittente

Ha un passaggio di "sincronizzazione" che può durare per diversi minuti e si tratta di un gruppo di chiamate di metodi asincroni che vanno a prendere JSON da un URL e inserirli nei dati principali. Abbastanza spesso, l'app si blocca (l'interfaccia utente non risponde).

Quali sono alcune buone tecniche per rintracciare questo congelamento? Il debugger non è così utile, a meno che il codice non sia in esecuzione sul thread principale, non ci sia traccia di stack utilizzabile. L'app spesso non recupera né suggerisce una sorta di situazione di blocco morto.

Ecco un esempio particolare che potrebbe aiutare:

enter image description here

mi fermai l'esecuzione una volta ho verificato che è stato congelato. Sembra congelarsi sulla stessa linea ogni volta - un compito semplice. Che cosa sta succedendo qui? È così frustrante.

Questo accesso ai dati di base sta causando questo? Qualsiasi suggerimento sarebbe molto apprezzato.

EDIT 29-Giugno-2012

Click here per vedere la fonte della classe che fa tutto il/Aggiornamento/Eliminazione Creazione di oggetti dati fondamentali. Ho solo bisogno di fermare il blocco/crash in questa app. So che è un casino, mi fa anche rabbrividire. Ho scritto questo 2 anni fa con pochissima conoscenza dell'obiettivo-c. Dovrei riscriverlo, ma devo farlo funzionare e uscire dalla mia testa in 2 giorni. Qualcuno potrebbe darmi dei suggerimenti sugli approcci per ottenere questo thread sicuro al più presto? Potrei avvolgere ogni metodo che aggiorna NSManagedObjectContext nel grande codice del blocco di invio centrale?

+1

Quando l'interfaccia utente non risponde è perché si sta eseguendo il codice sul thread principale che deve essere eseguito in background. Puoi provare a mettere in pausa l'app durante questo congelamento e, si spera, ottenere un'utile traccia di stack sul thread principale ... ma probabilmente non lo farai. L'unico modo che ho trovato davvero utile in questo scenario è l'essere davvero critico sul codice che stai eseguendo e dove. Verifica tutte le richieste Web e il codice relativo alla sincronizzazione e in qualsiasi altro luogo riteniate possa richiedere un processo intensivo. – Matt

+2

Un'altra idea (piuttosto che mettere in pausa il debugger e sperare per il meglio) potrebbe essere quella di eseguire l'app in Strumenti, che ti dirà quali metodi stanno usando più a lungo. Ho trovato molto utile per il debug di questi problemi. –

+0

Ho aggiornato la domanda con il link all'origine - se questo aiuta. –

risposta

2

In effetti è possibile che i Dati principali (in combinazione con il multithreading) siano la causa dei tuoi problemi - Ho riscontrato problemi simili.

Ecco un ottimo articolo su questo argomento: Core Data and threads, without the headache

vedo anche una chiamata a performSelector: nel vostro stack trace. Potresti prendere in considerazione l'utilizzo di Grand Central Dispatch, anche se potrebbe essere molto riscritto nel tuo caso.

Per quanto riguarda la tua domanda reale (rintracciare deadlock), suggerirei di utilizzare anche gli strumenti. Inoltre, guarda lo stato degli altri thread.

+0

Quindi avevi anche problemi di congelamento? –

+0

Sì, ho avuto problemi di congelamento e comportamento generale strano (e alcuni arresti anomali). Tutto ciò potrebbe essere risolto riducendo l'utilizzo di Core Data al thread principale, ma ho provato l'approccio nell'articolo menzionato in un progetto di test, e funziona (con più thread). –

0

Lei ha detto:

Il debugger non è così utile come meno che il codice è in esecuzione sul thread principale , non si ha traccia dello stack utilizzabile.

Questo non è vero. Ottieni tracce di stack per tutti i thread.

Il fatto che si blocchi ogni volta sulla stessa riga suggerisce che c'è qualcosa di sbagliato in quella linea.Questo è quello che state facendo:

self.friendObj.affiliations = friendObject1.affiliations; 

Quindi, vorrei mettere un punto di interruzione in quella riga e quando Xcode si ferma sul punto di interruzione, analizzare la memoria di friendObj1. Forse c'è qualcosa di funky in corso.

Esiste un metodo personalizzato "setAffiliations:" nella classe di friendObj? Forse in qualche modo si sta verificando un ciclo infinito su quella linea.

Vorrei analizzare tutte le chiamate intorno all'impostazione della proprietà "affiliazioni" del tuo amicoObj e provare a determinare dove si trova il tuo bug.

Un altro pensiero: friendObj è un oggetto Dati principali? Se è così, dovrebbe essere inizializzato in un ManagedObjectContext.

+0

No, non esiste un metodo setAffiliations personalizzato. È solo una stringa @ proprietà. friendObject1 è un oggetto coredata che è in errore quando eseguo il debug. Non ero troppo allarmato perché ho sentito che gli oggetti dati di base possono essere in uno stato di 'errore' se non sono ancora completamente risolti. –

+0

Se friendObj è un oggetto NSManagedObject (oggetto dati core), deve essere inizializzato utilizzando [NSEntityDescription insertNewObjectForEntityForName: @ "ClassName" inManagedObjectContext: myManagedObjectContext] –

+0

friendObj NON è un NSManagedObject - friendObj1 IS però. –

Problemi correlati