2013-05-26 2 views
5

Ich führe eine Reihe von Abfragen während des gesamten Lebenszyklus meiner App.Wann öffnen und schließen Sie eine SQlite DB im iOS-Lebenszyklus?

Ich verwende derzeit FMDB (Ein Objective-C Wrapper um die SQLite C API), und ich öffne und schließe vor jeder Abfrage.

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

öffnen und schließen Trigger fopen() und fclose() unten, so glaube ich, dass ich, indem die Datenbank öffnen einen notgedrungen Sieg gewinnen.

Ich glaube jedoch, temporäre Objekte werden aufgebaut, was zu Speicherproblemen führen könnte. Closing the database löscht die temporären Objekte.

  • Wann sollte ich die Datenbankverbindung öffnen und schließen? (z. B. Anwendung eingegeben Backgound?)
  • Sollte ich VACUUM in Situationen mit wenig Speicher ausführen?

Antwort

1

Datenbank erstellt und/oder behält keine Objekte (oder sollte es zumindest nicht). Die C-API ist nur eine praktische Möglichkeit, SQL-Abfragen zu verwenden, aber sobald diese ausgeführt werden, sollten sie freigegeben werden.

Jetzt für die zurückkehrenden Objekte einer Abfrage, die nur in Ihr FMResultSet kopiert werden. Sobald du veröffentlichst, sind sie weg.

Imo, wenn die Datenbank selbst nicht zu groß ist, sollten Sie in Ihrem App-Delegaten darauf Bezug nehmen (Garantie, um während der Lebensdauer Ihrer App am Leben zu bleiben). Wenn Sie die App/den Lebenslauf aus dem Hintergrund öffnen, öffnen Sie die Datenbank und wenn Sie in den Hintergrund/Schließen gehen, schließen Sie sie einfach.

Denken Sie daran, dass AppDelegate ein Singleton ist (ich denke) und Sie können auf Ihre Datenbank mit (AppDelegate*)[[UIApplication sharedApplication]delegate].your_db von überall in Ihrer App zugreifen, um die tatsächlichen Abfragen durchzuführen.

Die Verwendung von VACUUM stürzt Ihre App ab, wenn Sie versuchen, sie aufzurufen, wenn Sie eine Speicherwarnung erhalten. Denken Sie darüber nach: Um die Datenbank neu anzuordnen, sollte sie in den Speicher geladen werden (oder zumindest einen Teil davon), wenn Sie bereits eine Speicherwarnung haben ... poof ... crash.

Sie könnten testen, ob Ihre Datenbank Objekte im Speicher hält. Führen Sie einfach 100 Abfragen im 1s-Intervall (oder einen Tastendruck) aus und beobachten Sie in Instrumenten, wo und ob der Speicher wächst. Möglicherweise haben Sie ein Leck in Ihrer App (oder im Wrapper selbst) und Sie schieben es in die Datenbank.

+0

Vielen Dank für die Antwort. Sind Sie 100% sicher, dass die Datenbank keine Objekte erstellt und/oder behält? Sie haben wahrscheinlich Recht, aber diese Dokumentation sagt: "SQLITE_OK zurückgeben, wenn das sqlite3-Objekt erfolgreich zerstört wird ** und alle zugeordneten Ressourcen freigegeben werden" "Ich denke, http://www.sqlite.org/c3ref/close.html – Robert

+0

Die zugehörigen Ressourcen beziehen sich auf die Verbindung selbst und einige andere Dinge, auf die Sie zugreifen müssen. Wie ich sagte, bin ich nicht sicher, Server-Datenbanken tun dies. Andererseits müssen sie an sich nicht geöffnet werden. Tue es wie gesagt, teste es so: in einer separaten Klasse offene Datenbank, führe eine lächerliche Menge an Abfragen aus (während du den Speicher beobachtest) und schließe sie dann. Es sollte offensichtlich sein, was passiert. Wenn Sie ein Objekt behalten, werden Sie sehen, dass der Speicher weiter wächst, bis die App abstürzt, wenn nicht alles bei einer relativen konstanten Speicherzuweisung bleiben sollte. Das ist der einfachste Weg, um sicher zu gehen. – skytz

Verwandte Themen