Уведомления наблюдения значения ключа происходят в том же потоке, в котором наблюдалось изменение свойства. Apple упоминает следующее предупреждение в описании класса NSOperation:
"Хотя вы можете присоединять наблюдателей к этим свойствам, вы не должны использовать привязки Какао для привязки их к элементам пользовательского интерфейса вашего приложения. Код, связанный с вашим пользовательским интерфейсом, обычно должен выполняться только в главном потоке вашего приложения. Поскольку операция может выполнить в любом потоке, любые уведомления KVO, связанные с этой операцией, могут аналогичным образом появляться в любом потоке. "
В вашем методе observeValueForKeyPath:ofObject:change:context:
вы должны выполнять любые операции UIKit в главном потоке. Поскольку вы выполняете несколько шагов, вы можете создать другой метод в своем классе наблюдения с именем -dataLoadingFinished
, который можно вызывать в главном потоке изнутри observe:…
. После этого вы можете включить все свои вызовы пользовательского интерфейса вместо того, чтобы вызывать performSelectorOnMainThread
для каждого:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
[self performSelectorOnMainThread:@selector(dataLoadingFinished:) withObject:nil waitUntilDone:YES];
}
Даже в тех случаях, когда многопоточность не является проблемой, принято определять отдельные методы для фактической реализации каждого действия наблюдения, чтобы предотвратить слишком большое увеличение observe:…
.
Также обратите внимание, что, хотя вы наблюдаете только одно свойство, все же лучше проверить, что интересующее вас свойство - это то, что запрашивает уведомление об изменении. См. Статью Дэйва Дрибина Правильное использование КВО , чтобы узнать, как лучше всего это сделать.