Образ диска базы данных sqlite искажен на iPhone SDK - PullRequest
8 голосов
/ 14 октября 2010

У меня проблема с новым приложением на iPhone SDK, использующим SQLite в качестве бэкэнда БД.

Иногда мое приложение останавливает загрузку данных в мои UITableViews, и после загрузки БД устройства через Организатор я могу получить доступ к БД SQLite через командную строку. Я могу запросить некоторые таблицы нормально, но не другие, не получая ошибку «Ошибка SQL: образ диска базы данных искажен». Смотрите сеанс sqlite ниже:

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

В этом примере моя таблица пользователей работает нормально, но моя таблица элементов искажена, что соответствует тому, что я вижу в своем приложении, где элементы не загружаются. Приложение не падает, данные просто не загружаются из-за этой некорректной ошибки.

Есть идеи, почему это происходит? Я думал только о том, что, возможно, БД повреждена, потому что я пишу в БД SQLite через фоновый поток в приложении. Я загружаю данные с веб-сервера через NSOperationQueue в фоновом потоке и обновляю базу данных SQLite загруженными данными. Будет ли запись в БД в фоновом потоке (при потенциальном чтении из основного потока) повреждать БД или это что-то еще?

Ответы [ 3 ]

5 голосов
/ 07 февраля 2011

Вы должны быть очень осторожны с фоновыми потоками, обращающимися к базе данных во время отладки! Это связано с тем, что когда отладчик останавливает обработку (например, в точке останова), все потоки приостанавливаются, включая потоки, которые могут находиться в середине вызова базы данных, где-то между вызовом «open» базы данных и вызовом «close» базы данных. 1001 *

Если вы остановились на точке останова и нажали знак остановки в XCode, ваше приложение немедленно завершится. Это очень часто приводит к таким ошибкам, как та, которую вы видели, или ошибка «поврежденная база данных».

Там действительно нет никакого решения (потому что нет способа изменить поведение «остановить задачи», но я разработал некоторые методы, чтобы смягчить его: 1. Добавьте код, чтобы обнаружить приложение, входящее в фоновый режим, и ваши операции с БД изящно прекратятся. 2. Никогда не используйте знак остановки, чтобы остановить обработку во время отладки. Вместо этого, когда вы сделали точку останова, а затем «продолжить», нажмите кнопку «Домой» на симуляторе или устройстве (которая должна вызвать код, который вы добавили в шаге 1), подождите, пока приложение перейдет в фоновый режим, затем вы можете остановить запуск. *

5 голосов
/ 25 октября 2013

В моем случае это было связано с iOS 7: в iOS 7 Core Data теперь использует режим ведения журнала SQLite WAL, который записывает данные в файл .db-wal, а не напрямую в файл .db. В моем приложении я скопировал бы подготовленный файл .db в Library/Application Support во время обновления приложения. Проблема заключалась в том, что старый файл .db-wal все еще находился в этом каталоге, и я заменил только файл .db. Таким образом, я получил файл .db, который не был синхронизирован со старым файлом .db-wal.

Существует два решения этой проблемы:

  1. Убедитесь, что файлы .db, .db-wal и .db-shm удалены, прежде чем копировать новый файл .db на место.
  2. Вернитесь к старому поведению до iOS 7 следующим образом: https://stackoverflow.com/a/18870738/171933
0 голосов
/ 28 ноября 2010

Зависит от того, как SQLite скомпилирован, он может быть или не быть потокобезопасным. Если вы используете встроенный, он может не иметь параметров времени компиляции, которые вы ищете.

Для нашего приложения нам пришлось развернуть собственный SQLite, чтобы добавить полнотекстовый поиск. Взгляните на эту страницу .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...