CoreData:错误:在托管对象从其上下文中删除后对其进行变更

时间:2016-07-02 11:13:23

标签: ios swift core-data

我构建了一个简单的应用程序,检索一些JSON并将数据存储在Core Data中。

在模拟器或设备上进行初始安装后,所有Core Data操作都没问题,但重新运行后,我收到以下错误消息:

2016-07-02 13:23:53.925 En Yakın[84775:5379467] CoreData: error: Mutating a managed object 0x79736290 <x-coredata:///Category/t4B10F995-A717-4DB8-9E87-8A1C079D45D42> (0x79736250) after it has been removed from its context.

视觉上没有错。所有数据均按预期显示,并且应用程序正常运行。

我调试了这个问题。如果我注释掉JSON检索功能并使应用程序在初始运行后使用Core Data中的内容,则不会显示任何错误消息。但是再次检索应用程序会导致与我的核心数据堆栈(作为单个对象实现)的错误传达。

我应该如何修改我的核心数据实施?

更新

我相信我已将问题追踪到它的核心。我存储了大约6 KB的缩略图,我已经下载了。我发现存储图像会给Core Data带来性能损失。但是这种尺寸的缩略图也会有问题吗?如果我删除了对实体的图像分配,则错误消失。我应该将它们存储在文件结构中吗?

2 个答案:

答案 0 :(得分:2)

错误很有趣:

<x-coredata:///Category/t4B10F995-A717-4DB8-9E87-8A1C079D45D42>

请注意GUID前面的小写t。这意味着此对象是新的,尚未保存。因此,除非您在每次使用后抛弃未保存的托管对象上下文,这是一个完全有效的策略,否则您的状态不匹配。

解决问题的简单方法是发出更多save s或在每次新提取之前丢弃的子上下文中进行操作。

答案 1 :(得分:0)

如果您在 reset 上调用 NSManagedObjectContext,并在调用 reset 之前尝试使用插入到该上下文中的对象,则会发生这种情况。

let context = cdq.mainContext

let u = User.init(context: context)
u.name = "foo"

context.reset()

u.name = "bar"

这将导致 CoreData: error: Mutating a managed object 0xc9891a8bcbb85cb7 <x-coredata://505A879D-EC14-4A3E-8B6B-55BDD14DDC5D/Message/p260> (0x7b140009ee80) after it has been removed from its context. 错误。

这不一定会使应用程序崩溃。无论哪种方式,错误都会记录到控制台。

这样做也会导致 EXC_BAD_INSTRUCTION 崩溃,如下所示:

#0  0x00007fff2516b03e in -[NSManagedObjectContext _forceRegisterLostFault:] ()
#1  0x00007fff250b81bf in _PFFaultHandlerLookupRow ()
#2  0x00007fff250c1faf in _PF_ManagedObject_WillChangeValueForKeyIndex ()
#3  0x00007fff250c39a7 in _sharedIMPL_setvfk_core ()
#4  0x00007fff250dc290 in _sharedIMPL_copying_setvfk_core ()

来自 NSManagedObjectContext.reset() 上的 Apple 文档

<块引用>

接收者的所有管理对象都被“遗忘”。如果你使用这个方法,你应该确保你也丢弃对使用接收器获取的任何托管对象的引用,因为它们之后将是无效的。