2016-08-17 113 views
1

我有一个核心数据应用程序,其中包含由多个实体组成的单个模型。为了这个问题的目的,让我们调用模型“Person”并且拥有“name”(字符串),“age”(int),“职业”(字符串)和“description”(字符串)的实体。核心数据 - 重新启动应用程序时部分数据丢失

作为一个例子,我可以添加一个新的Person。我设定了他们的名字,年龄,职业和描述。我通过检查NSManagedObjectContextObjectsDidChangeNotification userInfo的内容确认上下文已更新。然后将上下文保存并保存到磁盘(通过日志记录和查询SQLite数据库进行确认)。

此时,我可以编辑我的任何Person对象,并且可以修改,添加,删除等所有实体,并且确认所有更改都通过NSManagedObjectContextObjectsDidChangeNotification更改上下文并且通过日志记录被确认保存到磁盘并查询SQLite - 一切都按预期工作。

但是,“职业”和“描述”在重新启动应用后不会持续。它们没有被设置为transient(但是它们是“可选的”),并且在设置主要上下文后(有时多次)。更重要的是,如果我退出应用程序,再次打开应用程序,我可以查询SQLite数据库并确认更改仍然存在于磁盘上。

当应用程序重新打开时,我可以确认磁盘上的所有内容与我退出时的相同。 但是,当我在我的应用代理中初始化核心数据时,NSManagedObjectContextObjectsDidChangeNotification通知我有些变化。出于某种原因,“职业”和“描述”已经消失。它们没有被设置为null,它们被设置为零长度的字符串。因此,下次发生触发保存的事件时,“职业”和“描述”被设置为零长度的字符串并消失。这一切都发生在启动 - 我不访问视图控制器或任何其他甚至查询这些特定领域。然而,我确实展示了一个视图控制器,它确实需要一个获取请求来填充显示People对象的UITableView,虽然它没有明确显示任何有问题的实体。

从Person 1到Person 2有一个轻量级的Core Data Model迁移,但是当切换回Person 1时,这个问题依然存在,这让我相信这不是迁移问题。

我在询问有关从哪里开始解决此问题的建议。我无法发布代码 - 我不知道在我的应用程序中发生问题的位置。我试图尽可能地进行故障排除,确认上下文中发生的更改以及与磁盘上的更改相比,我只是不知道该从哪里下载。我不知道为什么这些实体(以及其中一些实体)正在消失。有人会如何开始解决这类问题?任何帮助表示赞赏。

+0

在您的“人员管理对象模型”中,为有问题的属性创建自定义设置器并添加断点。如果这些实际上在应用程序重新启动时被修改,您应该会看到通过这些方法发生的情况,堆栈跟踪会为您提供有关谁正在调用它的提示。 – Rog

+1

如果将属性重命名为不同的东西,又会发生什么?试试'occup1'和'description1',看看问题是否存在,然后从那里开始。我敢肯定,你不应该使用'description'作为属性名称,因为它覆盖了'NSObject'实现的'description'。 Yup看到这里的文档说你不愿意重写'description',因为结果可能是不可预知的https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/LifeofaManagedObject.html# // apple_ref/doc/uid/TP40001075-CH16-SW1 – Rog

+0

在有问题的实体中,重写'validateValue:forKey:error',并添加条件代码,当'value'为空字符串且'key'为麻烦的领域。现在,在日志记录行上放置一个断点,通过回溯,您可以看到究竟是谁将字段设置为空字符串。 – Avi

回答

0

感谢@Rog和@Avi的指导,我能够为有问题的属性设置自定义设置器并覆盖validateValue:forKey:error,并在每个设置断点。从这里,我能够看到调用方法并正确诊断问题。

实际的问题是,当我初始化核心数据时,我误解了每个对象都要调用initWithEntity:insertIntoManagedObjectContext:,在这种印象中,只有在最初创建对象(一次且仅一次)时才会调用它。有问题的代码在initWithEntity:insertIntoManagedObjectContext:

谢谢你的帮助!

相关问题