2010-10-14 7 views
8

Je rencontre un problème avec une nouvelle application sur le SDK iPhone en utilisant SQLite comme le backend DB.sqlite disque image de base de données mal formé sur iPhone SDK

De temps en temps, mon application arrête de charger des données sur mes UITableViews et après avoir téléchargé la base de données de l'appareil via l'Organisateur, je peux accéder à la base de données SQLite via la ligne de commande. Je peux interroger certaines tables correctement mais pas d'autres sans obtenir une erreur "Erreur SQL: l'image de disque de base de données est mal formée". Voir une session sqlite ci-dessous:

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> 

Dans cet exemple ma table utilisateur fonctionne très bien, mais ma table d'article est malformé, ce qui correspond à ce que je vois dans mon application où les articles DonT charge. L'application ne plante pas, les données ne se charge pas à cause de cette erreur mal formée.

Des idées pour lesquelles cela se passe? Ma seule pensée est que peut-être la base de données est corrompue parce que j'écris à la base de données SQLite via un thread d'arrière-plan dans l'application. Je télécharge des données à partir d'un serveur Web via un NSOperationQueue dans un thread d'arrière-plan et met à jour la base de données SQLite avec les données téléchargées. Est-ce que écrire dans la base de données dans un thread d'arrière-plan (tout en lisant potentiellement à partir du thread principal) corromprait la base de données, ou est-ce autre chose?

Répondre

5

Vous devez être très prudent sur les threads d'arrière-plan qui accèdent à la base de données pendant le débogage! En effet, lorsque le débogueur interrompt le traitement (comme un point d'arrêt), tous les threads sont suspendus, y compris les threads qui se trouvent au milieu d'un appel de base de données, entre une base de données "open" et un appel "close".

Si vous êtes arrêté à un point d'arrêt et cliquez sur le signe d'arrêt dans Xcode, votre application se ferme immédiatement. Cela provoque très souvent des erreurs telles que celle que vous avez vu, ou l'erreur "base de données corrompue".

Il n'y a vraiment aucune solution (parce qu'il n'y a aucun moyen de modifier le comportement de "arrêter les tâches", mais j'ai développé certaines techniques pour l'atténuer: 1. Ajouter du code pour détecter l'application entrant en arrière-plan et 2. N'utilisez jamais le signe stop pour interrompre le traitement pendant le débogage, mais lorsque vous avez terminé avec un point d'arrêt, appuyez sur le bouton d'accueil du simulateur ou du périphérique (ce qui devrait déclencher le code que vous avez ajouté). dans l'étape 1), attendez que l'application soit en arrière-plan, puis vous pouvez arrêter l'exécution

0

Dépend de la façon dont SQLite est compilé, il peut ou non être thread-safe. Si vous utilisez la version intégrée, il se peut qu'elle ne contienne pas les options de compilation que vous recherchez.

Pour notre application, nous avons dû rouler notre propre SQLite pour ajouter la recherche en texte intégral. Jetez un oeil à this page.

5

Dans mon cas, cela a à voir avec iOS 7: Sur iOS 7, Core Data utilise maintenant le mode de journalisation SQLite WAL qui écrit des données sur un fichier .db-wal au lieu de directement vers le fichier .db. Dans mon application, je voudrais copier un fichier .db préparé dans Library/Application Support lors d'une mise à jour de l'application. Le problème était qu'un vieux fichier .db-wal était toujours dans ce répertoire et j'ai seulement remplacé le fichier .db. De cette façon, je me suis retrouvé avec un fichier .db qui n'était pas synchronisé avec l'ancien fichier .db-wal.

Il y a deux solutions à ce problème:

  1. Assurez-vous que le .db, .db-wal et .db-shm fichiers sont supprimés avant de copier votre nouveau fichier .db en place.
  2. Retour à l'ancien comportement pré-iOS 7 comme ceci: https://stackoverflow.com/a/18870738/171933
+0

Suppression des fichiers WAL et SHM totalement fait pour moi! Merci –

Questions connexes