2013-05-26 2 views
5

Eseguo una serie di query per tutto il ciclo di vita della mia app.Quando aprire e chiudere un database SQlite nel ciclo di vita di iOS?

Attualmente sto utilizzando FMDB (un wrapper Objective-C attorno all'AP C di Sqlite) e sto aprendo e chiudendo prima di ogni query.

FMDatabase * db = [FMDatabase databaseWithPath:pathToMyDB]; 
[db open] 
FMResultSet * s = [db executeQuery:@"SELECT * FROM myTable"]; 
// Use FMResultSet 
[db close]; 

Aprire e chiudere grilletto fopen() e fclose() più in basso, in modo da I belive che posso ottenere una vittoria per forza mantenendo il database aperto.

Tuttavia, credo che gli oggetti temporanei si accumuleranno, il che potrebbe causare problemi di memoria. Closing the database cancella gli oggetti temporanei.

  • Quando è necessario aprire e chiudere la connessione al database? (Ad esempio, l'applicazione ha inserito backgound?)
  • Devo eseguire VACUUM in situazioni di memoria insufficiente?

risposta

1

Il database non crea e/o conserva oggetti (o almeno non dovrebbe). L'API C è solo un modo pratico per utilizzare le query SQL, ma una volta che queste vengono eseguite dovrebbero essere rilasciate.

Ora, per gli oggetti di restituzione di una query, questi vengono copiati nel tuo FMResultSet. Una volta che lo hai liberato, sono spariti.

Imo, se il database stesso non è troppo grande, è necessario mantenere un riferimento ad esso nel delegato dell'app (garantire di essere vivo nel corso della vita della vostra app). Quando accedi all'app/riprendi dallo sfondo apri il database e quando vai in background/close basta chiuderlo.

Ricorda che AppDelegate è un singleton (credo) e puoi accedere al tuo database utilizzando (AppDelegate*)[[UIApplication sharedApplication]delegate].your_db da qualsiasi punto dell'app per eseguire le query effettive.

L'uso di VACUUM interromperà l'app se si tenta di richiamarla quando si riceve un avviso di memoria. Pensa a questo: per riorganizzare il database dovrebbe essere caricato in memoria (o almeno una parte di esso), se hai già un avviso di memoria ... poof ... crash.

È possibile verificare se il database conserva gli oggetti in memoria. Basta eseguire 100 query all'intervallo di 1 secondo (o premere un pulsante) e guardare negli strumenti dove e se la memoria aumenta. Potresti avere una perdita nella tua app (o nel wrapper stesso) e dare la colpa al database.

+0

Grazie per la risposta. Sei sicuro al 100% che il database non crei e/o mantenga alcun oggetto? Probabilmente hai ragione, ma questa documentazione dice: "restituisci SQLITE_OK se l'oggetto sqlite3 è stato distrutto con successo ** e tutte le risorse associate sono deallocate **" http://www.sqlite.org/c3ref/close.html – Robert

+0

Penso le risorse associate si riferiscono alla connessione stessa e ad alcune altre cose per cui è necessario accedervi. Come ho detto, non sono sicuro, i database dei server fanno questo. Poi di nuovo non hanno bisogno di essere aperti, di per sé. Fai come ho detto, prova come: in un database open class separato, esegui una quantità ridicola di query (mentre guardi la memoria) e poi chiudila. Dovrebbe essere ovvio cosa sta succedendo. Se conserva alcuni oggetti, vedrai che la memoria continua a crescere fino a quando l'app non si blocca, se non tutto dovrebbe rimanere in una costante allocazione di memoria relativa. Questo è il modo più semplice per essere sicuro. – skytz