Если я зарегистрируюсь за одно и то же событие несколько раз, он что-нибудь сделает? Или мне нужно отменить регистрацию много раз? Если последний, как я могу проверить, если я уже зарегистрирован для получения определенного события?Может ли какое-либо действие регистрировать наблюдателя несколько раз?
ответ
Вы будете получать уведомления несколько раз. Документы утверждают, что есть ситуации, когда вы захотите этого, хотя я не могу придумать ни одного.
Вы можете использовать removeObserver:
или removeObserver:name:object:
непосредственно перед добавлением наблюдателя, чтобы убедиться, что он не добавлен несколько раз. Нет ничего плохого в вызове removeObserver:
с объектом, который фактически не наблюдает за уведомлением.
В качестве альтернативы (и это, вероятно, самый высокий показатель производительности и самый надежный вариант) вы можете создать свой собственный объект NSSet
, чтобы точно хранить объекты, которые вы добавили к этому конкретному уведомлению, и проверить, добавляется ли тот, который вы собираетесь добавить дубликат.
Нет ничего плохого в вызове
removeObserver:
с объектом, который на самом деле не отслеживает уведомление.
Я пытался это сделать, потому что думал, что если бы он был реализован хорошо, он не пожаловался бы на удаление объекта без регистрации объекта в качестве наблюдателя. Но я получил исключение:
***, истекающий приложение из-за неперехваченного исключением «NSRangeException», причина: "Не удается удалить наблюдателя для ключевого пути„aKeyPath“из, потому что он не зарегистрирован в качестве наблюдателя.
Итак, вы должны управлять собой, если вы являетесь наблюдателем или нет. Это довольно смешно по сравнению с роскошью iOS-разработки.
Принятый ответ касается наблюдателей для уведомлений через NSNotificationCenter, а не для KVO (наблюдателей ключевых значений), которые действительно вызывают исключение для удаления. Иногда вам нужно просто поймать это исключение и двигаться дальше. – GreatWiz
NSString *obString = [NSString stringWithFormat:@"%@", session.observationInfo];
NSRange rangeOfKey = [obString rangeOfString:observedKey];
if (rangeOfKey.location != NSNotFound) {
//
NSLog(@"observing");
[session removeObserver:self forKeyPath:observedKey];
}
else {
//
NSLog(@"not observing");
}
Почему бы вам не попробовать и не посмотреть, что происходит? –