если вы указываете объекту c объект removeObservers: для ключевого пути, и этот ключевой путь не зарегистрирован, он взламывает sads. лайк -
«Невозможно удалить наблюдателя для ключевого пути« theKeyPath », поскольку он не зарегистрирован в качестве наблюдателя».
Есть ли способ определить, есть ли у объекта зарегистрированный наблюдатель, так что я могу сделать это
if (object has observer){
remove observer
}
else{
go on my merry way
}
objective-c
cocoa
key
key-value-observing
Аран Малхолланд
источник
источник
addObserver:
вviewWillAppear:
и , соответственно ,removeObserver:
вviewWillDisappear:
, звонки были состыкованы. Я должен сделать быстрое исправление, поэтому я собираюсь реализовать решение try-catch и оставить комментарий для дальнейшего изучения причины.Ответы:
Сделайте попытку поймать ваш вызов removeObserver
источник
Реальный вопрос в том, почему вы не знаете, соблюдаете ли вы это или нет.
Если вы делаете это в классе наблюдаемого объекта, остановитесь. Все, что наблюдает, ожидает, что продолжит наблюдать это. Если вы отключите уведомления наблюдателя без его ведома, ожидайте, что что-то сломается; более конкретно, ожидайте, что состояние наблюдателя устареет, поскольку оно не получает обновлений от ранее наблюдавшегося объекта.
Если вы делаете это в классе объекта наблюдения, просто запомните, какие объекты вы наблюдаете (или, если вы когда-либо наблюдаете только один объект, наблюдаете ли вы его). Это предполагает, что наблюдение является динамическим и находится между двумя иначе не связанными объектами; если наблюдатель владеет наблюдаемым, просто добавьте наблюдателя после того, как вы создадите или сохраните наблюдаемое, и удалите наблюдателя, прежде чем выпускать наблюдаемое.
Добавление и удаление объекта в качестве наблюдателя обычно должно происходить в классе наблюдателя, а не в классе наблюдаемого объекта.
источник
FWIW,
[someObject observationInfo]
кажется,nil
еслиsomeObject
нет наблюдателей. Однако я бы не стал доверять такому поведению, поскольку я не видел его документированным. Кроме того, я не знаю, как читать,observationInfo
чтобы получить конкретных наблюдателей.источник
objectAtIndex:
не дает желаемого результата.)NSKeyValueObserving.h
Единственный способ сделать это - установить флаг при добавлении наблюдателя.
источник
Когда вы добавляете наблюдателя к объекту, вы можете добавить его к
NSMutableArray
этому:Если вы хотите увидеть объекты, вы можете сделать что-то вроде:
Помните, если вы не наблюдаете один объект, удалите его из
_observedObjects
массива:источник
NSHashTable
/,NSMapTable
чтобы сохранить слабые ссылки.На мой взгляд - это похоже на механизм retainCount. Вы не можете быть уверены, что в текущий момент у вас есть наблюдатель. Даже если вы проверите: self.observationInfo - вы не можете точно знать, что у вас будут / не будут наблюдатели в будущем.
Нравится retainCount . Может быть, observationInfo метод не совсем такого рода бесполезна, но я только использовать его в целях отладки.
Так что в результате - вам просто нужно сделать это, как в управлении памятью. Если вы добавили наблюдателя - просто удалите его, когда он вам не нужен. Как использование методов viewWillAppear / viewWillDisappear и т. Д. Например:
И если вам нужны определенные проверки - реализуйте свой собственный класс, который обрабатывает массив наблюдателей, и используйте его для своих проверок.
источник
[self removeObserver:nil forKeyPath:@""];
нужно идти раньше:[super viewWillDisappear:animated];
- (void) setupSomething { [super setupSomething]; … } - (void) tearDownSomething { … [super tearDownSomething]; }
[someObject observationInfo]
Вернитесь,nil
если нет наблюдателя.источник
Весь смысл модели наблюдателя состоит в том, чтобы позволить наблюдаемому классу быть «запечатанным» - не знать или не заботиться о том, наблюдается ли он. Вы явно пытаетесь сломать эту модель.
Зачем?
Проблема, с которой вы сталкиваетесь, заключается в том, что вы предполагаете, что за вами наблюдают, а за вами нет. Этот объект не начал наблюдение. Если вы хотите, чтобы ваш класс контролировал этот процесс, вам следует рассмотреть возможность использования центра уведомлений. Таким образом, ваш класс полностью контролирует, когда можно наблюдать данные. Следовательно, все равно, кто смотрит.
источник
Я не фанат этого решения catch catch, поэтому большую часть времени я занимаюсь созданием метода подписки и отмены подписки для конкретного уведомления внутри этого класса. Например, эти два метода подписывают или отменяют подписку объекта на глобальное уведомление клавиатуры:
Внутри этих методов я использую приватное свойство, которое имеет значение true или false в зависимости от состояния подписки, например:
источник
В дополнение к ответу Адама я хотел бы предложить использовать такой макрос
пример использования
источник