核心数据:检测孩子何时被删除
Posted
技术标签:
【中文标题】核心数据:检测孩子何时被删除【英文标题】:Core data: detect when child has been deleted 【发布时间】:2015-11-09 16:10:12 【问题描述】:在我的应用中,我有一个Result
实体,它可以包含多个Expense
实体。
每个Expense
都有一个金额,我的Result
包含费用的总和。
当添加或删除 Expense
时,我需要自动计算该总和。
当我的Expense
被添加时,我已经成功地做到了这一点,从Expense
NSManagedObject
覆盖didChangeValueForKey
。但是,即使在删除生效时调用该方法,对Result
对象的引用也为零。我有一个想法使用willChangeValueForKey
来存储我的Result
对象的引用,但我觉得这很脏。
您是否有更好的主意,以便 Result 对象在其子对象之一被删除时得到通知?
【问题讨论】:
为 Result 创建 NSFetchedResutsController 怎么样,每次其中的某些内容发生变化时,控制器都会告诉你 您是否阅读了didChangeValueForKey:
的 NSManagedObject
文档?万一你错过了它,它说:你不能覆盖这个方法。
【参考方案1】:
我建议你像这样听 NSManagedObjectContextObjectsDidChangeNotification:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(dataModelHasChanged:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];
每次发生变化时,您都可以通过这种方式检测到:
- (void)dataModelHasChanged:(NSNotification *)notification
NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];
// Do something in response to this
【讨论】:
这很好,但我将结果存储回 Result 对象,这将导致无限循环 为什么会导致死循环?只需检测它是否被删除/插入,然后相应地扣除/添加总和 没有无限循环,但您缺少用户信息键。而且,这只在用户事件之后更新值(即,待处理的更改已被处理)。如果要进行主动缓存管理,还需要考虑其他边缘情况。一些最明显的:你会一直做计算吗?如果没有,你将如何决定?处理有缺陷的对象怎么办?您是要触发故障以获取数据,还是将其缓存?如果你缓存它,你会怎么做?等等等等……缓存管理很难。 如果我检查被删除的费用,我无权访问 Result 对象,因为它已经为零。如果我检查正在修改的结果,然后计算总和并修改它,它将导致无限循环。如果您对此有任何想法,我很乐意接受! 因此,每次您删除一个费用时,此方法都会调用两次:一次用于结果,一次用于费用。对吗?【参考方案2】:在我看来,Result
中的总和应该是一个计算属性。将总和存储在数据库中似乎是多余的。
请注意,使用 KVC 会非常高效:
let sum = self.expenses.valueForKeyPath("@sum.amount")
【讨论】:
有大量计算要做,因为我稍后会计算结果和其他统计数据的总和,我需要尽可能多地进行预计算。 您会惊讶于 Core Data 能以多快的速度进行此类计算。我已经建立了一个非常复杂的分析模型,它实际上在这种模式下表现得非常好,甚至包括涉及函数和递归的更复杂的计算。【参考方案3】:或者,您可以将计算属性添加到 Expenses
并在那里管理所需的副作用。
@NSManaged private var storedAmount: NSNumber
var amount: NSNumber
set
amount = newValue
storedAmount = amount
// do your computation and update Result
get return storedAmount
【讨论】:
以上是关于核心数据:检测孩子何时被删除的主要内容,如果未能解决你的问题,请参考以下文章