Отражать изменения объектов в отношении в родительском объекте с помощью NSFetchedResultsController

У меня есть два объекта события и время. Объект события имеет отношение от 1 до многих к объектам времени, так как каждое событие может выполняться несколько раз. Теперь я хочу показать хронологически все события в tableView. Поэтому я создал fetchedResultsController для извлечения всех объектов времени, сортировки их по времени начала и отображения информации о событии с помощью отношения к объекту события. Все идет нормально. Но теперь, если пользователь вставляет запись в таблицу, я передаю объект события в detailViewController, где можно изменить событие.

Проблема заключается в том, что теперь только объект события помечен как обновленный. Я нашел это, посмотрев каталог userInfo уведомления NSManagedObjectDidChange. Вследствие этого методы делегата в FRC не запускаются, поскольку никакие временные объекты не были изменены.

Как я могу вручную пометить объект времени как измененный, чтобы FRC распознал изменения и обновил ячейки соответственно? Я попытался запустить методы KVO willChangeValueForKey и didChangeValueForKey, но он пока не работает.

Спасибо большое Томас

Ответы

Ответ 1

Моя модель немного отличается, но ее можно легко перевести на ваш. Я получил древовидную структуру:

  • Элемент
    • название
    • parent (to-one)
  • Папка: Элемент
    • дети (для многих)
  • Файл: Элемент

Когда файл добавляется или удаляется, только первая папка в очереди получает уведомление об этом изменении. При изменении названия файла не будет уведомляться ни одна папка. Итак, что делать?
Я попытался переопределить -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. Надеюсь, это поможет решить вашу проблему.