我们的应用程序允许用户从 API 提供的列表中选择位置。该列表很少更新,并且仅通过添加项目来更新,因此应用程序不会每次都访问 API,而是在 Core Data sqlite 存储中提供快照,我们希望它定期更新列表。执行此操作的代码如下所示:
- 为线程创建托管对象上下文
- 从 API 获取完整列表
- for each one:
- 在上下文中查找具有匹配 locationID 的位置
- 如果没有找到,则在上下文中插入一个新的
- 使用新信息更新位置
- 保存上下文
当从空白数据库开始时,这工作得很好。但是,当我们第二次运行它时,它在保存过程中失败,并显示消息“SQL 执行期间错误:约束失败”。即使我将其限制在一个位置,它也会这样做。如果我打开 SQL 调试,我会看到以下内容:
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: COMMIT
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: INSERT INTO ZLOCATION(Z_PK, Z_ENT, Z_OPT, ZGEOID, ZCOUNTY, ZCOUNTRYCODE, ZNAME, ZLATITUDE, ZLONGITUDE, ZLANGUAGECODE) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
CoreData: error: (19) constraint failed
CoreData: annotation: Disconnecting from sqlite database due to an error.
然后它会重新连接并重试几次,然后放弃。
我的代码肯定会找到旧位置并且对象都是有效的 - 或者至少 [object validateForUpdate] 返回 YES。错误是什么意思?有没有办法找出哪个约束失败了?
如果我使用二进制存储,错误就会消失 - 但二进制存储是原子的,并且会在写入时阻塞很长时间。它看起来像是 sqlite 商店中的一个错误 - 有人找到解决方法吗?