CoreData:如何刷新“已计算”属性? [英] CoreData: How to refresh "calculated" attributes?

查看:76
本文介绍了CoreData:如何刷新“已计算”属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只要仅更改基本属性,我的NSFetchedResultsController就能很好地工作。但是,如果我有一个经过计算的标签,并且要更改一些影响该标签的属性,那么该标签将不会在导航控制器堆栈上的另一个视图控制器中更新。

My NSFetchedResultsController work great, as long as only "basic" attributes get changed. However if I have a label which is calculated and I'm changing some attributes influencing this label in another view controller on the navigation controller stack, this label doesn't get updated.

例如,我的标签应显示保存在实体SpendingCategory中的剩余预算职位量。

For example my label should show the amount of a budget position left saved in the entity SpendingCategory.

self.budgetLeftLabel.text = [NSString stringWithFormat:@"%@ %@", [[self.spendingCategory getExpendituresAmount] getLocalizedCurrencyStringWithDigits:0], NSLocalizedString(@"left", nil)];

我使用以下方法从SpendingCategory上的类别中得出该值:

I derive this value from the category on SpendingCategory with this method:

- (NSNumber *)getExpendituresAmount
{
    return [self.hasExpenditures valueForKeyPath:@"@sum.amount"];
}

但是NSFetchedResultsController不会对此标签进行任何更新。我的应用程序中有几个位置不会发生这种情况,因为会计算出一个值。我需要更改这些更新会发生什么?

However this label doesn't get any updates by the NSFetchedResultsController. And I have several locations in my app where this doesn't happen because a value is calculated. What do I need to change that these updates happen?

使用数据结构进行编辑:
好​​,我的支出类别数据结构大致(对于预算):

EDIT with datastructure: Ok my Spending Category datastructure is roughly (for budget):

name (string)
cost (double)
position (integer 16)
Relationsships: hasExpenditures

我的支出结构(用于跟踪):

My Expenditures structure (for tracking):

amount (double)
date (Date)
description (string)
Relationsships: forSpendingCategory

我希望现在更加清楚。那么为什么这些值不更新?

I hope it's clearer now. So why do these values not get updated?

推荐答案

NSFetchedResultsController 获取在相关的 NSManagedObject 实例中的属性被更新时,会被选中。如果您更改的是纯粹计算的内容,则更新永远不会触发。

The NSFetchedResultsController gets tickled when attributes in the relevant NSManagedObject instances are updated. If you are changing something that is purely calculated then the update never fires. Why is this relevant?

如果您要更改支出实体中的某些内容(顺便说一句,实体名称应为单数),并且您正在查看支出类别实体,则 NSFetchedResultsController 不会触发,因为您没有更改任何相关内容。

If you are changing something in the Expenditures entity (btw, entities should be singular in name) and you are watching the Spending Category entity then the NSFetchedResultsController won't fire because you didn't change anything that is relevant.

如何解决此问题?

取决于。我通常将派生的值保留在实体中并保持不变。此外,每当孩子更改相关值时,我都会让父母重新计算。这将导致 NSFetchedResultsController 触发。

Depends. I normally keep that derived value in the entity and persist it. Further, whenever a child changes a relevant value, I have the parent recalculate. This will cause the NSFetchedResultsController to fire.

您如何看待这些值?

要么让孩子在父级上调用方法(icky),要么让父级通过KVO监视其子级上的值(更好)。您的个人喜好在这里确定。

Either you have the child call a method on the parent (icky) or you have the parent watch the values on its children via KVO (better). Your personal preference decides here.

要在实体中保留派生值,请添加新归因于实体并存储。属性没有什么特别的。请记住,核心数据不是数据库。核心数据是您的数据模型,如果您愿意的话,它可以持久保存到数据库中。因此,在这种情况下,您想对数据库进行规范化

To keep the derived value in the entity you add a new attributed to the entity and store it. Nothing is special about the attribute. It helps to keep in mind that Core Data is not a database. Core Data is your data model that happens to persist to a database if you so choose. Therefore you want to denormalize the database in cases like this.

在我搜索SO以便找到看孩子的好链接时,我迷迷糊糊

while I was searching SO to find a good link for watching children, I stumbled across this example.

在多对多关系中的KVO对象属性

虽然接受的答案不是很好,但是第二个答案是使用 NSFetchedResultsController 非常有趣,值得探讨。基本思想是您的父对象在 -awakeFromFetch -awakeFromInsert <上实例化 NSFetchedResultsController / code>并在触发时重新计算派生值。因此,该值始终是最新的,并且由于父对象已更改,基于视图控制器的 NSFetchedResultController 实例将被触发。

While the accepted answer is not very good, the second answer, using a NSFetchedResultsController is quite interesting and is worth exploring. The basic idea is that your parent objects instantiate a NSFetchedResultsController on -awakeFromFetch or -awakeFromInsert and when it fires, they recalculate the derived value. Thus the value is always up to date and your view controller based NSFetchedResultController instances will fire because the parent object has changed.

这篇关于CoreData:如何刷新“已计算”属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆