2010-10-14 9 views
8

Ich habe ein Problem mit einer neuen Anwendung auf dem iPhone SDK mit SQLite als DB-Backend.sqlite Datenbank-Disk-Image auf iPhone SDK fehlerhaft

Gelegentlich beendet meine App das Laden von Daten in meine UITableViews und nach dem Herunterladen der Gerätedatenbank über den Organizer kann ich über die Befehlszeile auf die SQLite DB zugreifen. Ich kann bestimmte Tabellen in Ordnung aber nicht andere abfragen, ohne einen "SQL-Fehler: Datenbank-Disk-Image ist fehlerhaft" -Fehler. Hier finden Sie eine SQLite-Sitzung unter:

SQLite version 3.6.17 
    Enter ".help" for instructions 
    Enter SQL statements terminated with a ";" 
    sqlite> select * from user; 
    1|[email protected]|cpjolicoeur||4d055e38bb1d3758|image/gif|cartoonme_avatar.gif||Craig|Jolicoeur|1|1 
    sqlite> select * from item; 
    SQL error: database disk image is malformed 
    sqlite> 

In diesem Beispiel meine Benutzertabelle funktioniert gut, aber meine Artikel Tabelle ist falsch formatiert, das entspricht dem, was ich in meiner app sehe, wo die Elemente Last nicht. Die App stürzt nicht ab, die Daten werden aufgrund dieses fehlerhaften Fehlers nicht geladen.

Irgendwelche Ideen, warum das passiert? Mein einziger Gedanke ist, dass die DB möglicherweise beschädigt wird, weil ich über einen Hintergrund-Thread innerhalb der App in die SQLite-DB schreibe. Ich lade Daten von einem Webserver über eine NSOperationQueue in einem Hintergrundthread herunter und aktualisiere die SQLite DB mit den heruntergeladenen Daten. Würde das Schreiben in die Datenbank in einem Hintergrundthread (während möglicherweise aus dem Hauptthread gelesen wird) die DB beschädigen, oder ist es etwas anderes?

Antwort

5

Sie müssen sehr vorsichtig mit Hintergrund-Threads beim Debugging auf die Datenbank zugreifen! Wenn der Debugger die Verarbeitung anhält (z. B. an einem Haltepunkt), werden alle Threads pausiert, einschließlich Threads, die sich möglicherweise mitten in einem Datenbankaufruf befinden, irgendwo zwischen einem Datenbank- "Öffnen" und einem Datenbank- "Schließen" -Aufruf.

Wenn Sie an einem Haltepunkt angehalten werden und auf das Stopp-Symbol in Xcode klicken, wird Ihre App sofort beendet. Dies führt sehr oft zu Fehlern wie dem, den Sie gesehen haben, oder dem Fehler "beschädigte Datenbank".

Es gibt wirklich keine Lösung (weil es keine Möglichkeit gibt, das Verhalten von "stop tasks" zu ändern, aber ich habe einige Techniken entwickelt, um es zu mildern: 1. Fügen Sie Code hinzu, um die App zu erkennen, die den Hintergrund und Lassen Sie Ihre db-Operationen nicht stoppen 2. Verwenden Sie niemals das Stoppzeichen, um die Verarbeitung während des Debuggens zu stoppen.Wenn Sie mit einem Haltepunkt und dann "Weiter" fertig sind, drücken Sie die Home-Taste auf dem Simulator oder Gerät (was den hinzugefügten Code auslösen sollte) in Schritt 1), warten Sie auf die App im Hintergrund, DANN können Sie den Lauf stoppen

0

Je nachdem, wie SQLite kompiliert wird, ist es möglicherweise threadsicher. Wenn Sie den integrierten verwenden, verfügt er möglicherweise nicht über die Optionen für die Kompilierungszeit, nach denen Sie suchen.

Für unsere App mussten wir unsere eigene SQLite rollen, um eine Volltextsuche hinzuzufügen. Werfen Sie einen Blick auf this page.

5

In meinem Fall hatte dies mit iOS 7 zu tun: Auf iOS 7 Core Data verwendet jetzt den SQLite WAL Journaling-Modus, der Daten schreibt eine .db-wal Datei statt direkt zur .db Datei. In meiner App würde ich eine vorbereitete .db Datei in Library/Application Support während eines App-Updates kopieren. Das Problem war, dass eine alte .db-wal Datei immer noch in diesem Verzeichnis war und ich nur die .db Datei ersetzte. Auf diese Weise endete ich mit einer .db Datei, die mit der alten .db-wal Datei nicht synchron war.

Es gibt zwei Lösungen für dieses Problem:

  1. Sicherstellen, dass die .db, .db-wal und .db-shm Dateien gelöscht werden, bevor Sie Ihre neue .db Datei in Ort kopieren.
  2. zum alten pre-iOS 7 Verhalten wie so geht zurück: https://stackoverflow.com/a/18870738/171933
+0

die wal und shm Dateien löschen tat total es für mich! Vielen Dank –