NSManagedObject и KVO против документации

У меня есть собственный подкласс NSManagedObject, скажем, Person. У меня также есть UIView, зарегистрированный в -addObserver:forKeyPath:options:context:, чтобы наблюдать за различными свойствами Person, некоторые из которых являются постоянными, например, «name», а другие - просто тупыми KVO-совместимыми аксессуарами, не связанными с Core Data, например «выпивка».

@interface Person : NSManagedObject
{
    BOOL drinking;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, readonly) BOOL drinking;
@end

@implementation Person
@dynamic name;
...
- (void) getDrunk {
    [self willChangeValueForKey: @"drinking"];
    drinking = YES;
    [self didChangeValueForKey: @"drinking"];
}
...
@end

Все работает. Каждый раз, когда я отправляю -getDrunk или устанавливаю свойство name, представление получает уведомление. Я счастлив, за исключением тех случаев, когда читаю NSManagedObject документов, в которых говорится:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key

Факт 1. ДА, если получатель обеспечивает автоматическую поддержку уведомлений об изменении значения ключа, в противном случае НЕТ.

Факт 2. Реализация по умолчанию для NSManagedObject возвращает NO для смоделированных свойств и YES для немоделированных свойств.

Теперь я изо всех сил пытаюсь разобрать два приведенных выше факта из документов. Проверить факт 2 несложно, и класс Person действительно возвращает NO для @ "name" и YES для @ "drink". Но тогда как представление получает уведомление при изменении имени? Документы KVO четко говорят:

При использовании автоматических уведомлений наблюдателя нет необходимости заключать в скобки изменения свойства с вызовами willChangeValueForKey: и didChangeValueForKey: при изменении свойств с помощью методов, совместимых с кодированием значения ключа и кодированием значения ключа.

Итак, если Person возвращает NO из +automaticallyNotifiesObserversForKey: для @ "name", может показаться, что мне нужно вручную обернуть установщик имени в will/didChangeValueForKey:, чтобы KVO заработал. Однако KVO работает нормально. Что мне не хватает? Какой смысл в NSManagedObject переопределении +automaticallyNotifiesObserversForKey: и его документировании, если не кажется, что стандартное поведение KVO меняется?

Пожалуйста, помогите мне восстановить рассудок.


person Costique    schedule 16.09.2010    source источник


Ответы (2)


Что ж, NSManagedObject предоставляет реализацию для свойства name (а также методов - name и - setName:). Я предполагаю, что реализации, предоставляемые Core Data, действительно включают вызовы willChangeValueForKey: и didChangeValueForKey:.

Итак, хотя KVO является "автоматическим" в том смысле, что вам не нужно ничего делать, чтобы заставить его работать, я могу представить, что он не автоматический в том смысле, что willChangeValueForKey: и didChangeValueForKey: вызывается методами в NSManagedObject, которые предоставляют реализации динамических свойств.

person Alex    schedule 16.09.2010
comment
Ваше объяснение имеет смысл. Большое спасибо! - person Costique; 16.09.2010

I also have a UIView registered with -addObserver:forKeyPath:options:context

Задача контроллера - взять данные из модели и установить их в представлении, а также по ходу их форматировать. Представление должно иметь возможность отображать данные из любой модели, а не только человека - думаю, заголовок, подзаголовок, а не имя. Также контроллер может получать изменения из представления и применять их к модели, а также фильтровать уведомления от модели, чтобы предотвратить ненужное возвращение вещей обратно в представление, откуда они только что пришли.

person malhal    schedule 09.08.2020