我想清理一些瞬態屬性重新計算事件。在開發過程中,我幾乎對所有變化都進行了非常廣泛的更新。現在我正在嘗試確定最佳做法,檢查相關密鑰並根據需要進行更新。我的應用程序對象使用子和父屬性進行了數十次計算,其中單個更改可能導致許多級聯重新計算。NSManagedObjectContext不通知觀察者變化的瞬變
我以爲我理解的很好,指的是蘋果文檔here,並且我嘗試了在其他一些StackOverflow帖子上看到的模式,比如this @Marcus S. Zarra。我看到馬庫斯也發佈了關於這個主題here的文章。
什麼我現在是這樣的:
#pragma mark _ worksheetTotal (transient)
+(NSSet *)keyPathsForValuesAffectingWorksheetTotal
{
// local, non-transient, dependent keys here
return [NSSet setWithObjects:@"dailySustenance", nil];
}
-(void)updateWorksheetTotal
{
NSDecimalNumber *lineItemTotal = [self.items valueForKeyPath:@"@sum.lineHoursCost"];
NSDecimalNumber *total = [lineItemTotal decimalNumberByAdding:self.dailySustenance];
[self setWorksheetTotal:total];
}
-(void)setWorksheetTotal:(NSDecimalNumber *)newWorksheetTotal
{
if ([self worksheetTotal] != newWorksheetTotal) {
[self willChangeValueForKey:@"worksheetTotal"];
[self setPrimitiveWorksheetTotal:newWorksheetTotal];
[self didChangeValueForKey:@"worksheetTotal"];
}
}
-(NSDecimalNumber *)worksheetTotal
{
[self willAccessValueForKey:@"worksheetTotal"];
NSDecimalNumber *result = [self primitiveWorksheetTotal];
[self didAccessValueForKey:@"worksheetTotal"];
return result;
}
我想這是直接從文檔的使用情況,但我的觀察沒有得到通知的變化來worksheetTotal。
當對lineItem進行更改時,會收到該通知並在此處調用updateWorksheetTotal
。我希望這會觸發另一個通知,即工作表總計現在已更改的上下文,但事實並非如此。我已經嘗試了許多變體和我已經看到的代碼組合,但我沒有做任何事情似乎使NSManagedObjectContext
認爲我的更新爲worksheetTotal
是值得向觀察員報告的變化。
缺少什麼我在這裏?
以下是用於監聽父對象更改的相關代碼。
- (void) objectContextDidChange: (NSNotification *) notification
{
NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
// Next look for changes to worksheet that may affect our calculated fields
NSPredicate *worksheetPredicate = [NSPredicate predicateWithFormat:@"entity.name == %@ && estimate == %@", @"LaborWorksheet", self];
NSPredicate *materialsPredicate = [NSPredicate predicateWithFormat:@"entity.name == %@ && estimate == %@", @"MaterialLineItems", self];
NSPredicate *combinedPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:worksheetPredicate, materialsPredicate, nil]];
NSSet *myWorksheets = [updatedObjects filteredSetUsingPredicate:combinedPredicate];
// These are the relevant keys in this estimates labor and materials worksheet
NSSet *relevantKeys = [NSSet setWithObjects:@"worksheetTotal", @"totalEquipmentcost", nil];
BOOL clearCache = NO;
if (myWorksheets.count != 0) {
for (NSManagedObject *worksheet in myWorksheets) {
NSLog(@"got some");
// Here is where it fails, worksheetTotal is not in changedValues.allKeys. It is an empty set.
// Not sure how that could be when I got it from updatedObjects set of userInfo. How could it have no changed values?
NSSet *changedKeys = [NSSet setWithArray:worksheet.changedValues.allKeys];
if ([changedKeys intersectsSet:relevantKeys]) {
clearCache = YES;
NSLog(@"found some, set to clear cache");
// no need to continue checking
break;
}
}
}
if (clearCache) {
// I would update dependent keys here but it is never reached
}
}
你的觀察者如何傾聽這種變化? –
@JesseRusak我在 –