6

我对 Core Data 比较陌生(来自 SQLite 背景)。刚读完“iOS 核心数据”一书,但当我开始为具有以下模型的应用程序建模时,我留下了许多令人费解的问题:

  1. 具有一对多“交易”关系和“起始余额”属性的“帐户”实体
  2. 具有一对多“付款”关系的“交易”实体(与帐户相反)
  3. “付款”实体,包含实际支付的“金额”的详细信息

出于性能原因,我想对模型进行非规范化并在“Accounts”实体中添加一个“TotalAmountSpent”属性(如书中建议的那样),以便在发生变化时继续更新它。

在实践中,这似乎很难通过 Core Data 实现。我不知道如何正确地做到这一点(也不知道正确的方法是什么)。所以我的问题是:

a) 我应该将“TotalAmountSpent”更改为 Fetched 属性吗?是否存在性能影响(我知道它是延迟加载的,但我几乎肯定会为每个帐户获取该属性)。如果我这样做,我需要能够获得在给定时间段(例如过去三天)内针对“startingBalance”所花费的总金额。这在 SQL 中似乎很容易,但我如何在 Core Data 中做到这一点?我读到我可以使用@sum 聚合函数,但是如何使用@sum 过滤“日期”?我还阅读了数据中的任何更改都需要刷新获取的属性。我如何“倾听”变化?我是否在“付款”实体的“willSave”方法中执行此操作?

b) 每次将新付款添加到交易中时,我是否应该使用传播并手动更新“TotalAmountSpent”?最好的地方是什么?我应该在重写的 NSManagedObject 的“willSave”方法中执行此操作吗?如果帐户上的“startingBalance”字段已更新,我担心更新所有相应的交易/付款将是一场噩梦。然后,我必须加载每笔付款并计算支出总额和帐户的最终余额。如果有成千上万的付款,那就太可怕了

任何有关此事的指导将不胜感激。谢谢!

4

1 回答 1

8

如果您使用获取的属性,则无法在不先将数据加载到内存中的情况下轻松查询该属性。因此,我建议您将实际的非规范化数据保留在实体中。

实际上有几种方法可以轻松地保持最新状态。

  1. 在您的-awakeFromFetch/-awakeFromInsert设置将影响价值的关系的观察者。然后,当 KVO(键值观察器)触发时,您可以进行计算并更新字段。学习 KVC 和 KVO 是一项宝贵的技能。

  2. 您可以-willSaveNSManagedObject子类中覆盖并在保存时进行计算。虽然这更容易,但我不推荐它,因为它只会在保存时触发,并且不能保证您的帐户对象会被保存。

无论哪种情况,您都可以使用KVC 集合运算符非常快速地进行计算。使用集合运算符,您可以通过调用来进行求和:

NSNumber *sum = [self valueForKeyPath:@"transactions.@sum.startingBalance"];
于 2011-09-27T16:53:39.617 回答