Отражать изменения объектов в отношении в родительском объекте с помощью NSFetchedResultsController
У меня есть два объекта события и время. Объект события имеет отношение от 1 до многих к объектам времени, так как каждое событие может выполняться несколько раз. Теперь я хочу показать хронологически все события в tableView. Поэтому я создал fetchedResultsController для извлечения всех объектов времени, сортировки их по времени начала и отображения информации о событии с помощью отношения к объекту события. Все идет нормально. Но теперь, если пользователь вставляет запись в таблицу, я передаю объект события в detailViewController, где можно изменить событие.
Проблема заключается в том, что теперь только объект события помечен как обновленный. Я нашел это, посмотрев каталог userInfo уведомления NSManagedObjectDidChange. Вследствие этого методы делегата в FRC не запускаются, поскольку никакие временные объекты не были изменены.
Как я могу вручную пометить объект времени как измененный, чтобы FRC распознал изменения и обновил ячейки соответственно? Я попытался запустить методы KVO willChangeValueForKey
и didChangeValueForKey
, но он пока не работает.
Спасибо большое
Томас
Ответы
Ответ 1
Моя модель немного отличается, но ее можно легко перевести на ваш.
Я получил древовидную структуру:
- Элемент
- Папка: Элемент
- Файл: Элемент
Когда файл добавляется или удаляется, только первая папка в очереди получает уведомление об этом изменении. При изменении названия файла не будет уведомляться ни одна папка. Итак, что делать?
Я попытался переопределить -willChangeValueForKey: и -didChangeValueForKey: в классе Element.
- (void)willChangeValueForKey:(NSString *)key
{
[super willChangeValueForKey:key];
[self.parent willChangeValueForKey:@"children"];
}
- (void)didChangeValueForKey:(NSString *)key
{
[super didChangeValueForKey:key];
[self.parent didChangeValueForKey:@"children"];
}
В основном, это означает, что родительская папка обновляется, потому что один из ее детей изменился.
Надеюсь, это сработает и для вас.
Ответ 2
Ответ выше от @Jenox кажется правильной идеей, но лучше не переопределять эти методы, поскольку они вызываются всякий раз, когда какой-либо ключ изменяется на дочерний объект и, вероятно, будет влиять на производительность и вызывать неожиданные побочные эффекты ( это было для меня). Вероятно, лучше всего просто называть их каким бы способом вы не вносили изменения в дочерний объект, например:
- (void)updateFromDictionary:(NSDictionary *)aDictionary {
[myParentModel willChangeValueForKey:@"myChildObject"];
[super updateFromDictionary:aDictionary];
[myParentModel didChangeValueForKey:@"myChildObject"];
}
Обратите внимание, что updateFromDictionary
- один из моих методов, а не системный метод.
Ответ 3
Я тоже работаю над некоторыми подобными обновлениями. Вот как я подошел к проблеме.
Скажем, у нас есть объект A, относящийся к объекту B. B имеет свойство C. Мы хотим, чтобы изменения в свойстве C отражались в FRC, которые используют A в качестве извлеченного объекта. То, что я сделал, чтобы это произошло, это определить аксессуар свойства C из объекта A:
//A.m
- (void)setC:(int)cValue {
[self willChangeValueForKey:@"b"];
self.b.c = cValue
[self didChangeValueForKey:@"b"];
}
- (int)c {
return self.b.c;
}
Это позволило моим ячейкам обновляться на основе обратных вызовов FRC с типом NSFetchedResultsChangeUpdate. Надеюсь, это поможет решить вашу проблему.