2010-10-14 68 views
8

Tôi gặp sự cố với ứng dụng mới trên SDK iPhone bằng SQLite làm phụ trợ DB.Hình ảnh đĩa cơ sở dữ liệu sqlite không đúng định dạng trên iPhone SDK

Thỉnh thoảng, ứng dụng của tôi sẽ ngừng tải dữ liệu vào UITableViews của tôi và sau khi tải xuống thiết bị DB qua Trình tổ chức, tôi có thể truy cập DB SQLite qua dòng lệnh. Tôi có thể truy vấn một số bảng tốt nhưng không truy vấn được những người khác mà không nhận được lỗi "Lỗi SQL: hình ảnh đĩa cơ sở dữ liệu bị sai". Xem phiên sqlite bên dưới:

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> 

Trong ví dụ này bảng người dùng của tôi không đúng định dạng, tương ứng với những gì tôi thấy trong ứng dụng của tôi nơi các mục không tải. Ứng dụng không bị lỗi, dữ liệu không tải do lỗi không đúng định dạng này.

Bất kỳ ý tưởng nào tại sao điều này đang xảy ra? Suy nghĩ duy nhất của tôi là có thể DB bị hỏng vì tôi đang viết cho DB SQLite qua một luồng nền trong ứng dụng. Tôi tải xuống dữ liệu từ máy chủ web qua NSOperationQueue trong luồng nền và cập nhật DB SQLite với dữ liệu đã tải xuống. Sẽ viết cho DB trong một chủ đề nền (trong khi có khả năng đọc từ các chủ đề chính) bị hỏng DB, hoặc là nó cái gì khác?

Trả lời

5

Bạn phải rất cẩn thận về các chủ đề nền truy cập cơ sở dữ liệu trong khi gỡ lỗi! Điều này là bởi vì khi trình gỡ lỗi dừng xử lý (chẳng hạn như tại điểm ngắt), tất cả các luồng đều bị tạm dừng, bao gồm các luồng có thể ở giữa cuộc gọi cơ sở dữ liệu, ở đâu đó giữa cơ sở dữ liệu "mở" và một cuộc gọi "đóng" cơ sở dữ liệu.

Nếu bạn bị tạm dừng tại điểm ngắt và nhấp vào Xcode dừng đăng nhập, ứng dụng của bạn sẽ thoát ngay lập tức. Điều này thường gây ra các lỗi như lỗi bạn gặp phải hoặc lỗi "cơ sở dữ liệu bị hỏng". Có thực sự không phải là giải pháp nào (vì không có cách nào để thay đổi hành vi "ngừng nhiệm vụ", nhưng tôi đã phát triển một số kỹ thuật để giảm thiểu nó: 1. Thêm mã để phát hiện ứng dụng đang chạy nền và Bạn có thể sử dụng dấu dừng để dừng quá trình xử lý trong khi gỡ lỗi, thay vào đó, khi thực hiện xong một điểm dừng thì "tiếp tục", nhấn nút home trên trình mô phỏng hoặc thiết bị (sẽ kích hoạt mã bạn thêm vào ở bước 1), hãy đợi ứng dụng chạy nền, THEN bạn có thể dừng chạy.

0

Phụ thuộc vào cách SQLite được biên dịch, nó có thể hoặc có thể không an toàn cho luồng. Nếu bạn đang sử dụng tính năng tích hợp sẵn, nó có thể không có các tùy chọn biên dịch mà bạn đang tìm kiếm.

Đối với ứng dụng của chúng tôi, chúng tôi đã phải cuộn SQLite của riêng mình để thêm tìm kiếm toàn văn bản. Hãy xem this page.

5

Trong trường hợp của tôi, điều này liên quan đến iOS 7: Trên iOS 7 Core Data hiện sử dụng chế độ ghi nhật ký WAL của SQL tệp .db-wal thay vì trực tiếp vào tệp .db. Trong ứng dụng của tôi, tôi sẽ sao chép tệp được chuẩn bị .db vào Library/Application Support trong khi cập nhật ứng dụng. Vấn đề là một tệp cũ .db-wal vẫn còn trong thư mục đó và tôi chỉ thay thế tệp .db. Bằng cách đó, tôi đã kết thúc bằng một tệp .db không đồng bộ với tệp .db-wal cũ.

Có hai giải pháp cho vấn đề này:

  1. Hãy chắc chắn rằng .db, .db-wal.db-shm tập tin được xóa trước khi bạn sao chép .db tập tin mới của bạn vào vị trí.
  2. Quay trở lại các hành vi cũ trước iOS 7 như sau: https://stackoverflow.com/a/18870738/171933
+0

Xóa các tập tin wal và shm hoàn toàn đã làm nó cho tôi! Cảm ơn –

Các vấn đề liên quan