Как программно отслеживать объект KVC?

#objective-c #xcode #macos #key-value-observing #key-value-coding

#objective-c #xcode #macos #наблюдение за ключом-значением #кодирование ключ-значение

Вопрос:

Я пытаюсь отслеживать NSMutableArray на предмет изменений с помощью кода. Я хочу добавить наблюдателя для каждого изменения массива, но я не вижу, каким должно быть NotificationName, чтобы это произошло.

В принципе, когда массив изменен, я хочу выполнить пользовательский селектор.

Ответ №1:

Я не уверен на 100%, но я почти уверен, что наблюдение за значением ключа — это то, что вы хотите.

Какой бы объект ни был, который заботится о массиве, регистрирует себя в качестве наблюдателя:

 [objectWithArray addObserver:self 
                  forKeyPath:@"theArray"
                     options:NSKeyValueObservingOptionNew 
                     context:nil];
  

Затем он получит уведомление о том, что массив изменился:

 - (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context {

    NSLog(@"Change is good: %@", [change objectForKey:NSKeyValueChangeNewKey]);
}
  

Обратите внимание, что этот единственный метод соберет все наблюдения, для которых зарегистрирован этот объект. Если вы регистрируете один и тот же объект для наблюдения за множеством разных ключей, вам, вероятно, придется различать их при вызове этого метода; это цель аргументов keyPath и object .

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

 [self willChangeValueForKey:@"theArray"];
[theArray addObject:...];
[self didChangeValueForKey:@"theArray"];
  

Произвольный класс фреймворка будет иметь некоторые свойства, которые соответствуют, и некоторые свойства, которые не соответствуют соблюдению ключевого значения. Например, NSWindow ‘s firstResponder совместим с KVO, но его childWindows нет. Документы, конечно, скажут вам, что есть что.