Core data CoreData:如何刷新";“计算的”;属性?

Core data CoreData:如何刷新";“计算的”;属性?,core-data,Core Data,只要只更改“基本”属性,我的NSFetchedResultsController就工作得很好。但是,如果我有一个已计算的标签,并且我正在更改导航控制器堆栈上另一个视图控制器中影响此标签的某些属性,则不会更新此标签 例如,“我的标签”应显示实体支出类别中剩余的预算头寸金额 self.budgetLeftLabel.text = [NSString stringWithFormat:@"%@ %@", [[self.spendingCategory getExpendituresAmount] ge

只要只更改“基本”属性,我的NSFetchedResultsController就工作得很好。但是,如果我有一个已计算的标签,并且我正在更改导航控制器堆栈上另一个视图控制器中影响此标签的某些属性,则不会更新此标签

例如,“我的标签”应显示实体支出类别中剩余的预算头寸金额

self.budgetLeftLabel.text = [NSString stringWithFormat:@"%@ %@", [[self.spendingCategory getExpendituresAmount] getLocalizedCurrencyStringWithDigits:0], NSLocalizedString(@"left", nil)];
我使用此方法从SpendingCategory上的类别中导出此值:

- (NSNumber *)getExpendituresAmount
{
    return [self.hasExpenditures valueForKeyPath:@"@sum.amount"];
}
但是,NSFetchedResultsController不会对此标签进行任何更新。我在我的应用程序中有几个位置没有发生这种情况,因为计算了一个值。要更改这些更新,我需要做什么

使用数据结构编辑: 好的,我的支出类别数据结构大致如下(预算):

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


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

当更新相关
NSManagedObject
实例中的属性时,
NSFetchedResultsController
会被勾选。如果您正在更改纯计算的内容,则更新不会触发。为什么这是相关的

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

如何解决这个问题

视情况而定。我通常将该派生值保留在实体中并将其持久化。此外,每当子对象更改相关值时,我都会让父对象重新计算。这将导致
NSFetchedResultsController
启动

你是如何看待这些价值观的

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

更新1 若要将派生值保留在实体中,请向实体添加新的属性并将其存储。属性没有什么特别之处。请记住,核心数据不是数据库。核心数据是您的数据模型,如果您选择的话,它恰好会持久化到数据库中。因此,在这种情况下,您需要对数据库进行非规范化

当我在寻找一个好的链接来观察孩子时,我偶然发现了这个例子


虽然公认的答案不是很好,但第二个答案,即使用
NSFetchedResultsController
非常有趣,值得探索。基本思想是父对象在
-awakeFromFetch
-awakeFromInsert
上实例化一个
NSFetchedResultsController
,当它触发时,它们重新计算派生值。因此,该值始终是最新的,并且基于视图控制器的
NSFetchedResultController
实例将启动,因为父对象已更改。

我以前做过类似的事情,基本上您需要将计算出的值存储在CoreData模型中的瞬态属性中,而不是实现自己的setter和getter。然后在相关的NSManagedObject中,您需要实现两种方法:

// this will populate the values when 
// the entity is retrieved from the store
-(void)awakeFromFetch {
  [self refreshCellInfo];
}

// this will refresh the values when
// the object goes to fault
// (for example when it is off screen)
-(void)willTurnIntoFault {
  [self refreshCellInfo];
}

-(void)refreshCellInfo {
  // update all your derived values...
}

您能描述一下您的模型结构吗?self.hasExpensions支持并填充了哪些内容?嗯,好的,您能举个例子说明如何通过KVO查看这些值吗?以及如何在实体中保留派生值的示例?还是coredata的新手,所以我很高兴学习。
amount (double)
date (Date)
description (string)
Relationsships: forSpendingCategory
// this will populate the values when 
// the entity is retrieved from the store
-(void)awakeFromFetch {
  [self refreshCellInfo];
}

// this will refresh the values when
// the object goes to fault
// (for example when it is off screen)
-(void)willTurnIntoFault {
  [self refreshCellInfo];
}

-(void)refreshCellInfo {
  // update all your derived values...
}