2015-08-07 15 views
7

Ho un errore che alcuni utenti hanno di EXC_BAD_ACCESS quando il loro dispositivo ha poca memoria. L'analisi dello stack è puntato sulla linea if qui sotto, e credo che sia a causa della UTF8String che viene deallocata e ancora in uso:Objective-C - Come forzare la memoria insufficiente sul simulatore iOS

dispatch_sync(dbQueue, ^{ 
    if (sqlite3_bind_text(sql_stmt, 1, pid.UTF8String, -1, SQLITE_STATIC) != SQLITE_OK) { 
... 

Sto avendo un momento difficile che riproduce il problema da parte mia, come può Io forza o simulo la memoria bassa sul simulatore o su un dispositivo?

Aggiornamento:

Ho provato ad aggiungere un punto di interruzione alla riga precedente, e quindi utilizzando l'opzione Simulator -> Simula Memory Attenzione, ma non riesco ancora a riprodurre l'errore EXC_BAD_ACCESS.

risposta

3

Nel menu del simulatore: Hardware-> Simula avviso memoria.

Aggiornamento

Se sei sicuro che la vostra applicazione si è schiantato al sqlite3_bind_text, suppongo il problema più potenziale potrebbe essere che il pid.UTF8String è NULL volte nel qual caso si provoca crash. Inoltre, è improbabile che pid o pid.UTF8String venga deallocato quando viene utilizzato, è possibile controllare il rapporto sugli arresti anomali (se ne esiste uno) e controllare l'indirizzo della memoria che ha causato l'EXC_BAD_ACCESS, ad esempio se si dispone di EXC_BAD_ACCESS CODE=2 ADDRESS=0x00000000 , significa pid.UTF8String è davvero un puntatore NULL, se l'indirizzo non è 0x0, quindi, è un altro problema (molto improbabile nel tuo caso).

Come suggerimento, si prega di aggiungere nil controllare il codice:

if (pid) { 
    if (sqlite3_bind_text(sql_stmt, 1, pid.UTF8String, -1, SQLITE_STATIC) != SQLITE_OK){ 
    // do your stuff 
    } 
} else { 
    sqlite3_bind_null(sql_stmt,1); 
} 
+0

Da quello che ho capito, l'opzione genera solo un avviso e chiama un metodo come "didReceiveMemoryWarning", ma riproduce anche lo stesso comportamento di un dispositivo con poca memoria? – heitortsergent

+0

sì. http://stackoverflow.com/a/5892435/2574577 –

+1

grazie per il link @MaxvonHippel! Ho provato a utilizzare questa opzione e ho aggiornato la domanda, ma non riesco ancora a riprodurre l'errore EXC_BAD_ACCESS – heitortsergent

4

Nel simulatore v'è una voce di menu: Hardware: Simula memoria Attenzione

o

spostamentocomandoM

0

Sul lato sinistro della schermata di XCode è possibile visualizzare un pulsante per aprire Debug Navigator, in cui è possibile vedere la quantità di memoria attualmente utilizzata dall'app e la quantità gratuita.

Se lo analizzi, ti renderai conto che la memoria disponibile per il tuo simulatore è la stessa del tuo computer, quindi ti suggerisco di eseguire alcune applicazioni che utilizzano molta memoria contemporaneamente al simulatore.

Se si dispone di un iPad a disposizione potrebbe essere più facile, quello che di solito fare è andare su questo website e copiare come gran parte del tavolo unicode il più possibile, in modo che verrà memorizzato sul tavolo di montaggio

0

Molte volte, questi tipi di errori sono il risultato di una "tempesta perfetta" di circostanze (ad es. condizioni di gara, attività poco frequenti che si svolgono solo al "giusto" orario, ecc.), e spesso il tipo di circostanze che non si possono prevedere; se sapessi come riprodurlo in modo affidabile, probabilmente sapresti anche come risolverlo. La prossima cosa migliore che puoi sperare è provare ad aumentare le tue probabilità statistiche di riprodurlo in un ambiente (il debugger) dove potresti sperare di dare un senso a ciò che sta accadendo.

Vedere questo post: iOS Development: How can I induce low memory warnings on device?. Simulando programmaticamente gli avvisi di memoria, è possibile (ad esempio) utilizzare un timer ripetuto per causare un avviso di memoria di 1/sec (molto più veloce di quello e si potrebbero incappare in altri problemi, il che ti farà inseguire più che risolvere il tuo problema originale), eliminando la necessità di farlo ripetutamente a mano.

Prima effettivamente in esecuzione del test, è possibile anche impostare i punti di interruzione ai seguenti posizioni:

Symbol          Module 
======          ====== 
objc_exception_throw       libobjc.A.dylib 
-[NSException raise]       CoreFoundation 

Inoltre, impostare punti di interruzione su tutte le eccezioni Objective-C. L'impostazione di un punto di interruzione consente di ispezionare il contenuto della memoria prima che l'eccezione venga effettivamente generata dal runtime, che offre una possibilità molto migliore di comprendere il problema quando si verifica. Quando (e se) acquisisci l'incidente, controlla pid, pid.UTF8String e sql_stmt, in quanto sembrano i colpevoli più probabili.

Esegui la tua app e avvia il timer. Questo non sarà necessariamente o direttamente causa l'incidente che stai cercando, ma probabilmente renderà molto più probabile che si verifichi nel tempo senza doverlo tenere in mano; puoi spegnere il timer e attendere (ad esempio, fare qualcosa di più produttivo) finché non vedi effettivamente l'incidente.

Problemi correlati