Я пытаюсь очистить некоторые события перераспределения свойств переходных процессов. В разработке я только что использовал очень широкий ход обновления практически для всех изменений. Теперь я пытаюсь определить наилучшую практику, проверять соответствующие ключи и обновлять как можно меньше. Мои объекты приложения загружаются десятками вычислений с использованием дочерних и родительских атрибутов, где одно изменение может привести к каскадным перерасчетам.NSManagedObjectContext не уведомляет наблюдателя об изменениях для переходных процессов
Я думал, что понял довольно хорошо, ссылаясь на документацию Apple here, и я экспериментировал с шаблонами, замеченными на некоторых других сообщениях StackOverflow, таких как this один by @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.
При внесении изменений в строкуItem это уведомление получено и отвечает updateWorksheetTotal
. Я ожидаю, что это приведет к еще одному уведомлению в контексте, что рабочий листTotal теперь изменился, но это не так. Я пробовал множество вариаций и комбинаций кода, который я видел, но ничего не делает, что делает 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 Я добавил пример на вопрос –