核心数据迁移丢失 NSNumber 值

发布于 2024-09-24 15:07:59 字数 580 浏览 0 评论 0原文

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

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

[temp setNumUses:temp.numUses+1];

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

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

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

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

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

想法?

After migration, one of my numerical values that should be non-zero now appears as zero. If I don't migrate, the value retains its non-zero value.

I first tried to set a number value in a managed object like this:

[temp setNumUses:temp.numUses+1];

... but that caused an'EXC_BAD_ACCESS' so I changed it to:

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

... but after migration, this code claimed that hold was initialized as an int with a value of 0 when before running the new code its value was clearly 1 or more (referring to the test object which was used only 1 time).

When I do not migrate the Core Data Database the NSNumber retains its value fine through many context saves and application terminations.

What might I be missing? I have some extensive code that modifies values of changed NSManagedObjects in a database stored elsewhere but none of it tampers with 'numUses'.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倦话 2024-10-01 15:07:59

最简单的解释是,迁移以某种方式让 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];

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

The simplest explanation is that the migration somehow convinces Core Data that numUses is a new attribute with default value of zero. The reason for this would be in the migration model and not in the assignment code you have provided.

However, the code in the parent does suggest you don't quite understand NSNumber and miss using NSNumber elsewhere might cause your problem.

NSNumber is only an object wrapper around numerical values. You can't perform operations with it. That is why this line:

[temp setNumUses:temp.numUses+1];

... causes the EXC_BAD_ACCESS. As you discovered, you have to convert a NSNumber to an int or NSDecimalNumber to perform mathematical operations on it.

This line:

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

... will leak memory. You initialize a NSNumber object but never release it. In this case (and the vast majority of all cases), you should use the class methods to create NSNumbers because they return an autoreleased object that won't leak. So:

[temp setNumUses:[NSNumber numberWithInt:hold];

In general, it is bad practice to initialize any object in a method parameter. You are asking for nasty memory leaks that will be very hard to track down. The report of the leak may not show up in the code where the method is called but in the method itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文