Как сообщить (управляемому) объекту, чтобы он уведомлял свои KVO о том, что одно из его свойств необходимо повторно кэшировать?

Когда у нас есть объект, у которого есть свойство, сгенерированное на основе других свойств, обычно мы реализуем метод класса +keyPathsForValuesAffecting{PropertyName}.

То, что я пытаюсь сделать, в основном то же самое для свойства в моем NSManagedObject, но через отношение.

Моя модель проста; У меня есть две сущности, приложение и версия (я создаю приложение, генерирующее приложение). Когда свойства приложения изменяются, поскольку я реализовал описанный выше метод, строка -appcast изменяется, и все привязки обновляются соответствующим образом.

Однако при изменении каких-либо свойств в любой из конкретных версий приложения (отношение ко многим) свойство -appcast не создается должным образом. Я могу исправить/обходной путь?


person Steven    schedule 25.07.2009    source источник
comment
Для ясности: appCast — это свойство App, и когда вы меняете значения в Version (которое предположительно связано с App через свойство versions или подобное), свойство appCast не отправляет уведомление об изменении?   -  person Alex    schedule 26.07.2009


Ответы (1)


Это немного запоздалый ответ, но я думаю, что это обычная ситуация, и ответ определенно не очевиден.

Обычно я наблюдаю за изменением manageObjectContext, а затем проверяю, не являются ли какие-либо из измененных объектов теми, на которые я хочу обратить внимание. Итак, в вашем подклассе NSManagedObject:

// We need to register for the notification in both awakeFromFetch
// AND awakeFromInsert, since either one could be called, depending on
// if the object was previously-created or not
- (void)awakeFromFetch {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)awakeFromInsert {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)managedObjectContextDidChange:(NSNotification *)notification {
    // Get a set containing ALL objects which have been changed
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];

    NSSet *changedObjects = [insertedObjects setByAddingObjectsFromSet:updatedObjects];
    changedObjects = [changedObjects setByAddingObjectsFromSet:deletedObjects];

    if ([changedObjects intersectsSet:[self versions]]) {
        [self willChangeValueForKey:@"appCast"];
        [self didChangeValueForKey:@"appCast"];
    }
}

Это, конечно, не идеально с точки зрения производительности, так как это уведомление будет срабатывать каждый раз, когда что-либо в вашем графе объектов изменяется, но я считаю, что это самый простой способ добиться этого.

person Matt Ball    schedule 01.09.2009