核心数据迁移丢失 NSNumber 值

Posted

技术标签:

【中文标题】核心数据迁移丢失 NSNumber 值【英文标题】:Core Data Migration loses NSNumber value 【发布时间】:2010-09-26 03:40:40 【问题描述】:

迁移后,我的一个本应为非零的数值现在显示为零。如果我不迁移,该值将保留其非零值。

我首先尝试在托管对象中设置一个数值,如下所示:

[temp setNumUses:temp.numUses+1];

...但这导致了“EXC_BAD_ACCESS”,所以我将其更改为:

int hold = ((int)[[temp valueForKey:@"numUses"] intValue]);
hold++;
[temp setNumUses:[[NSNumber alloc] initWithInt:hold]];

...但是在迁移之后,这段代码声称hold在运行新代码之前被初始化为一个值为0的int,而它的值显然是1或更大(指的是仅使用的测试对象1 次)。

当我不迁移核心数据数据库时,NSNumber 通过许多上下文保存和应用程序终止保持其价值。

我可能缺少什么?我有一些广泛的代码可以修改存储在其他地方的数据库中更改的 NSManagedObjects 的值,但没有一个会篡改“numUses”。

想法?

【问题讨论】:

【参考方案1】:

最简单的解释是迁移以某种方式使 Core Data 相信 numUses 是一个默认值为零的新属性。其原因在于迁移模型,而不是您提供的分配代码。

但是,父代码中的代码确实表明您不太了解 NSNumber 并且错过在其他地方使用 NSNumber 可能会导致您的问题。

NSNumber 只是数值的对象包装器。您无法使用它执行操作。这就是为什么这一行:

[temp setNumUses:temp.numUses+1];

... 导致EXC_BAD_ACCESS。正如您所发现的,您必须将 NSNumber 转换为 int 或 NSDecimalNumber 才能对其执行数学运算。

这一行:

[temp setNumUses:[[NSNumber alloc] initWithInt:hold]];

... 会泄漏内存。你初始化了一个 NSNumber 对象,但从不释放它。在这种情况下(以及绝大多数情况下),您应该使用类方法来创建 NSNumber,因为它们返回一个不会泄漏的自动释放对象。所以:

[temp setNumUses:[NSNumber numberWithInt:hold];

一般来说,在方法参数中初始化任何对象都是不好的做法。您要求的是很难追踪的令人讨厌的内存泄漏。泄漏报告可能不会显示在调用方法的代码中,而是显示在方法本身中。

【讨论】:

嗨,我想指出我在使用 Objective-C 编程方面相对较新。我确实在分​​配之前尝试了 NSNumber 类方法,但我想覆盖我的所有基础以确保。无论哪种方式,仍然存在 NSNumber 值为 0 的问题。你有什么关于核心数据迁移模型的建议吗?要在我的代码中迁移数据库,我只是按照添加自动迁移的指南进行操作,是否还有更好的方法/简单的方法来使用该方法解决此问题? 另外,为什么会:[temp setNumUses:temp.numUses+1];最终工作?我不久前编写了该代码,该代码已被替换,但在迁移之前它确实有效。是否有写入 NSNumber 的运算符方法?还是这些不存在?谢谢! NSNumber 没有操作符方法。您不能只将标量添加到 NSNumber 对象。如果你尝试,你实际上会增加对象的地址。我不知道您的迁移失败的原因。 是否有指导我正确迁移核心数据数据库的指南?

以上是关于核心数据迁移丢失 NSNumber 值的主要内容,如果未能解决你的问题,请参考以下文章

在 CoreData 实体中将属性从 NSNumber 转换为 NSString - LightWeightMigration

迁移复杂的核心数据模型

核心数据迁移是不是必要?

Coredata轻量级迁移丢失数据

轻量级迁移核心数据

通过迁移更改表结构而不丢失数据?