2

这个问题是关于使用 Dropbox 在多个 iOS 设备之间同步一个 sqlite Core Data 存储。考虑这种安排:

  1. 一个应用程序使用一个核心数据存储,调用它local.sql,保存在应用程序自己的NSDocumentDirectory

  2. 该应用程序使用 Dropbox Sync API 来观察用户 Dropbox 中的某个文件,例如,user/myapp/synced.sql

  3. 该应用程序观察NSManagedObjectContextDidSaveNotification,并在每次保存时复制local.sqluser/myapp/synced.sql,从而替换后者。

  4. 当 Dropbox API 通知我们synced.sql更改时,我们或多或少地做了与第 3 部分相反的操作:拆除 Core Data 堆栈,替换local.sqlsynced.sql,然后重新创建 Core Data 堆栈。同时,用户会在 UI 中看到“正在同步”或“正在加载”。

问题:

A. 这种安排是否非常低效,到了应该完全避免的程度?如果我们能保证数据库不大呢?

B. 这种安排是否有利于文件损坏?不仅仅是通过 deltas/changelogs 同步?如果是这样,请您详细解释为什么?

4

1 回答 1

7

A. 这种安排是否非常低效,到了应该完全避免的程度?如果我们能保证数据库不大呢?

无关紧要,因为:

B. 这种安排是否有利于文件损坏?不仅仅是通过 deltas/changelogs 同步?如果是这样,请您详细解释为什么?

是的,非常如此。几乎保证。我建议查看How to Corrupt An SQLite Database File。您可能会立即提交第 1 节中描述的至少两个问题,包括在事务处于活动状态时复制文件和删除(或无法复制,或制作无用的副本)日志文件。在任何严肃的测试中,您的方案很可能几乎立即分崩离析。

如果这还不够糟糕,请考虑两个设备同时保存更改的情况。然后怎样呢?如果幸运的话,您只会得到 Dropbox 臭名昭著的“冲突副本”文件副本之一,“仅”意味着丢失一些数据。如果没有,您将再次陷入完全数据库损坏。

当然,为了同步而拆除 Core Data 堆栈会给用户带来极大的不便。

如果您想考虑通过 Dropbox 同步 Core Data,我建议您采用以下方法之一:

  1. Ensembles,可以通过 Dropbox(同时避免上述问题)或 iCloud(同时避免 iOS 内置的 Core Data/iCloud 同步问题)进行同步。
  2. TICoreDataSync,它使用 Dropbox 文件同步但避免将 SQLite 文件放入文件存储中。
  3. ParcelKit,它使用 Dropbox 的新数据存储 API。(请注意,这是相当新的,数据存储 API 本身仍处于测试阶段)。
于 2013-07-25T00:09:23.000 回答