【发布时间】:2019-03-06 07:04:44
【问题描述】:
我花了一个工作日的大部分时间来解决这个问题。
背景
我有一个简单的核心数据模型,包含书籍和阅读会话。这些书的封面(图片)以二进制数据的形式存储为“允许外部存储”。
在 iOS 11.4 及更低版本上,一切正常。当我保存一个新会话时,一切都会正确更新。
问题
从 iOS 12 开始,当我创建一个新的阅读会话并将其链接到图书时,大约每 秒 次,核心数据都会生成一条 SQL 语句,该语句也会更新图书封面字段,有时会导致一个错误的引用(对磁盘上的文件),这通常会导致重新启动应用程序时封面为 nil,并且几乎总是会在磁盘上创建封面的重复副本(如 Simulator 的 _EXTERNAL_DATA 所示文件夹)。
内存中的上下文和对象仍然正确(因此 UI 中的一切都正常),直到应用程序重新启动,然后封面通常是 nil。
iOS 12 特定
在 iOS 12 上,我可以确定性地在模拟器中、物理设备上重现该错误,并且用户也报告了该错误。我无法在 iOS 11.4 上重现该错误,并且在 iOS 12 之前没有用户报告该错误。
采取的步骤
我已启用“
-com.apple.CoreData.ConcurrencyDebug 1”,因此不应该是我从错误的队列中访问任何内容。我还启用了“-com.apple.CoreData.SQLDebug 3”,这样我就可以准确地看到写入的内容。在我做
newSession.book = book和context.save()之前,我通过检查hasChanges确保我的代码在与新会话关联之前没有修改Book 实例(以及封面) .为了 100% 确定我没有触及任何线程上的封面属性,我已经短路了该属性的 getter 和 setter。没有改善。
我尝试使用
objectID在关联之前请求图书的实例并保存。没有改善。我什至尝试了上下文保持对所有对象的强引用的选项,只是为了确保它不是某种内存管理问题。没有改善。
问题
对下一步有什么想法吗?
状态更新
这是 iOS 12 中的一个缺陷。有关合理解决方法的详细说明,请参阅下面接受的答案。
【问题讨论】:
-
我想我遇到了完全相同的问题。对此的任何解决方法或解决方案将不胜感激!
-
我认为我们遇到了同样的错误,尽管还有一些其他用例。 forums.developer.apple.com/thread/109189
-
我们体验到将图片保存到coredata外部存储成功,但是重启应用后,图片无法访问并返回nil。 iOS 12 的主要错误。 :(
-
在 Bugtracker 上报告,越多越好。