【问题标题】:How to update attribute everytime a new object is added in CoreData?每次在 CoreData 中添加新对象时如何更新属性?
【发布时间】:2014-07-28 02:32:18
【问题描述】:

我有一个如下所示的核心数据模型:

注意MonthlyYearSalePCSParticularProduct 实体中的total 属性和array 关系;与其他实体之间的关系遵循one-to-many 关系。

进一步说明:

PCSParticularProduct 实体的total 属性存储特定产品 ID 中当月的总销售额。

MonthlyYearSale 实体的total 属性存储基于当月大约 24 种产品的总销售额集合计算的每月总销售额。

问题:

当我在父实体的数组中添加子对象时,如何更新同一父实体的total 属性?我有两个实体,我希望根据添加到array 关系属性中的对象更新total 图。有没有有效的方法来做到这一点?

【问题讨论】:

    标签: ios objective-c core-data ios7


    【解决方案1】:

    您不应该使用 CoreData 字段来管理这些值,因为它们是计算值。除非您有数千个对象并且一遍又一遍地计数成为性能问题,否则保存它们没有任何好处。但到那时,您将不再使用 CoreData,而是直接使用 SQLite。

    您可以按如下方式实现总计:

    .h:

    @property (readonly) int total
    

    .m

    - (int)total;
    {
         int subTotal = 0;
         for (ProductSale sale in self.arrayOfChildren)
         {
              subTotal = subTotal + sale.value;
         }
    
         return subTotal;
    }
    

    它将作为一个属性工作,但它每次都会为您提供实际值。我很确定它需要将所有对象读入内存,如果不是这种情况,您应该进一步研究 Core Data 聚合:

    How to count in coredata (aggregation)?

    我建议,如果您需要对数据(如聚合)使用大量类似 SQL 的函数,您应该调查一下直接使用 SQLite 是否是更好的选择。基于 SQL 的 CoreData 更适合以相关方式存储模型,而不是实际的数据库:

    http://www.objc.io/issue-4/SQLite-instead-of-core-data.html

    也许您可以混合使用这两种方法,但我不知道如果您同时通过 CD 访问同一个数据库会如何。

    【讨论】:

    • 感谢您的发帖。是的,我有超过 15,600 个对象并且还在增长,所以一遍又一遍地计数将成为一个性能问题,因此是我的问题。附言我正在使用核心数据,以便我可以从关系中受益,并且仅在需要时访问关系数据。必须有一种有效的方法来处理 arrayOfChildren 的总值。作为旁注,绑定在这种情况下会有所帮助吗?
    • 我假设所有对象都没有在内存中准备好,所以我的方法已经不够用了。然后看这里:stackoverflow.com/questions/3342540/… 也很好读:objc.io/issue-4/SQLite-instead-of-core-data.html 我更新了我原来的答案
    • 看看哪里?你说看看herethen,我收到了then 链接但没有here 链接。
    • @Pavan 我不确定如何将这些 cmets 编辑为更易读的状态,但在我的原始回复和下面的评论中有两个可点击的链接。 ** 第一个链接--> ** stackoverflow.com/questions/3342540/… ** 第二个链接--> ** objc.io/issue-4/SQLite-instead-of-core-data.html
    【解决方案2】:

    您可以在 managedObject 子类中创建一个包装器方法,例如

    - (void) insertChild:(NSManagedObject *)object {
    
    call core data method to add the object (or set the object's parent)
    update total
    }
    

    或者您可以使用 KVC 来观察子数组的变化并通过更新总数来响应。我会推荐包装方法,因为它不需要实例化父对象。

    【讨论】:

    • 您能否详细解释一下您的 KVC 方法。在定义关系时,coredata 已经添加了一种方法,该方法允许您向数组添加/删除子项,但添加子项当然不会更新特定属性,例如我的 total 属性,这些属性可以在前两个实体中找到我的 coredata 模型图。
    • 你可以观察到数组的变化(见developer.apple.com/library/mac/documentation/cocoa/reference/…)。当一个对象被插入到数组中时,你的 managedObjectSubclass 的 observeValueForKeyPath 函数可以更新总数。也许更好的(也是另一种)方法是在保存父对象时更新总数,假设它有更改。保存对象时,会调用 managedObjectSubclass 的 -willSave 函数,您可以在那里进行计算。
    • 最后一种方法的另一种做法是让每个新的子对象在保存子对象时更新父对象的总数,并且更改会影响父对象的总数。
    • 这就是我最终做的匹克威克。日期现在加载速度非常快,当然那是因为所有内容都已缓存。只有初始下载需要永远,因为它从过去一年中获取了数千个销售日期。但是一旦文件在本地更新,我只获取自上次使用日期处理程序更新数据以来的数据。它很酷。
    猜你喜欢
    • 1970-01-01
    • 2012-11-03
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多