ios - 如何在保存之前自动设置计算的 NSManagedObject 属性?

标签 ios core-data nsmanagedobject

假设我有一个名为 ItemNSManagedObject 子类。每当保存 item 实例时,我都想根据 transient 属性的计算值更新属性。我知道我可以在 transient 属性发生变化时更新属性,但对于这个问题,假设我有充分的理由不想这样做。

我尝试在 willSave 方法中执行此操作,如下所示:

- (void)willSave
{
    self.computedProperty = [self computedValueFromTransientProperty];
}

这会在保存上下文时导致崩溃。如果我将代码移出 willSave 并在调用保存之前明确设置该属性,它就可以正常工作。 Apple 文档说您应该避免在 willSave 中更改托管对象属性。

问题:是否有一种将功能构建到 NSManagedObject 子类中的好方法,这样就可以在保存之前更新属性,而无需从类外部显式设置属性,并且无需每次 transient 属性更改时设置属性?

最佳答案

您可以从 willSave 设置持久属性, 你只需要更加小心。

来自willSave文档:

This method can have “side effects” on persistent values. You can use it to, for example, compute persistent values from other transient or scratchpad values.

If you want to update a persistent property value, you should typically test for equality of any new value with the existing value before making a change. If you change property values using standard accessor methods, Core Data will observe the resultant change notification and so invoke willSave again before saving the object’s managed object context. If you continue to modify a value in willSave, willSave will continue to be called until your program crashes.

所以,发生的事情是你正在改变 computedProperty ,这导致了willSave再次调用,这会改变 computedProperty这叫willSave再次,直到你的程序崩溃。

要解决此问题,您需要检查是否 computedProperty需要重新设置:

- (void)willSave
{
    id computed = [self computedValueFromTransientProperty];
    if (![self.computedProperty isEqual:computed])
    {
        self.computedProperty = computed;
    }
}

这意味着 computedValueFromTransientProperty将被调用两次,因此如果该方法的计算量很大,您可能不想这样做。

另一种选择是使用原始集合方法,这意味着 willSave不会被调用两次,但可能会产生副作用,具体取决于您的应用与 Core Data 的交互方式:

- (void)willSave
{
    self.primitiveComputedProperty = [self computedValueFromTransientProperty];
}

关于ios - 如何在保存之前自动设置计算的 NSManagedObject 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8176762/

相关文章:

ios - 如何获取当前单元格的indexPath

ios - 将 sectionNameKeyPath 与 NSFetchedResultsController 一起使用

ios - CoreData 到 CloudKit 迁移

ios - Nullify 和 Cascade 之间的区别,在核心数据中拒绝

swift - 失败的 NSManagedObject 仍在保存

ios - 我正在尝试制作一款横向卷轴游戏,但我正在努力无限地生成地面

ios - ObjC 将文本文件行添加到 PickerView

javascript - 动画和 Wow JS

core-data - NSPredicate 用于 NSManagedObject 的字符串属性的长度

ios - 来自不同上下文的对象,即使它们不是