Что использовать в качестве ключевого пути в КВО? - PullRequest
6 голосов
/ 13 февраля 2012

У меня есть контроллер представления с изменяющимся представлением (например), и я хотел бы наблюдать кадр любого представления, для которого установлено self.view. Есть ли разница между:

[self.view addObserver:self forKeyPath:@"frame" options:0 context:nil];

и

[self addObserver:self forKeyPath:@"view.frame" options:0 context:nil];

Во втором случае, если изменения вида будут по-прежнему приниматься, когда изменяется кадр нового вида, или он будет отправлять сообщения только в том случае, если кадр вида, который был установлен при добавлении наблюдателя?

Есть ли способ наблюдать за изменениями свойства кадра, даже если вид контроллера контроллера изменяется после добавления наблюдателя?

Ответы [ 2 ]

7 голосов
/ 13 февраля 2012

Используйте второй путь.@"view.frame" будет уведомлять вас об изменениях фрейма, даже когда меняется сам «вид».Какао автоматически добавит наблюдателей для каждого объекта в «цепочке» keyPath автоматически (это означает, что каждый элемент в keyPath должен быть KVO-совместимым).

2 голосов
/ 02 ноября 2013

Вы спросили, есть ли разница между ними, Ответ - да, есть разница между ними:

Первый

говорит "я как представление", я добавляю наблюдателя с именем self (aka) viewControllerObject, если вы вызывали это в viewController.m всякий раз, когда мое свойство с именем "frame" изменяется.

Второй

Говорит "я как ViewController". Я добавляю себя как AsAnObserver всякий раз, когда изменяется ключ KeyPath с именем "view.frame".

Поскольку каждый наблюдатель должен реализовать

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

В этом случае вы не заметите большой разницы, потому что вы добавили viewController в качестве наблюдателя в любой из описанных выше методов, но это будет иметь значение, когда вы имеете дело с различными объектами. Но правило простое, каждый добавленный наблюдатель должен реализовать

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

Еще одна вещь: Хорошая идея создать контекст для наблюдения например,

//In MyViewController.m 

//.. 
static int observingViewFrameContext


// In ...
[self addObserver:self 
       forKeyPath:@"view.frame" 
          options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld 
          context:&observingViewFrameContext];


// .. don' forget to remove an observer ! too 
...