Swift: добавление / удаление наблюдателей в init / deinit вызывает ошибку в Interface Builder

#ios #cocoa #swift

#iOS #какао #swift

Вопрос:

У меня есть простой компонент пользовательского интерфейса swift (https://github.com/mbigatti/BMXCircularButton ) это можно проверить. В init / deinit methods у меня есть вызовы для запуска и остановки наблюдения выделенного состояния.

 init(frame: CGRect) {
    super.init(frame: frame)
    self.addObserver(self, forKeyPath: "highlighted", options: .New, context: nil)
}

init(coder aDecoder: NSCoder!) {
    super.init(coder: aDecoder)
    self.addObserver(self, forKeyPath: "highlighted", options: .New, context: nil)
}

deinit {
    self.removeObserver(self, forKeyPath: "highlighted")
}
 

Выполнение этого вызывает ошибки в построителе интерфейса со следующими ошибками:

 file:///Users/max/Progetti/StatusApp/CircularButton/CircularButton/View.xib: error: 
Live Views: Failed to update auto layout status: Interface Builder Cocoa Touch Tool raised a "NSRangeException" 
exception: Cannot remove an observer <_TtC17BMXCircularButton14CircularButton 0x10ba98e00> 
for the key path "highlighted" from <_TtC17BMXCircularButton14CircularButton 0x10ba98e00> because it is not registered as an observer.

file:///Users/max/Progetti/StatusApp/CircularButton/CircularButton/View.xib: error: 
Live Views: Failed to render instance of _TtC17BMXCircularButton14CircularButton: Interface Builder Cocoa Touch Tool raised a "NSRangeException" 
exception: Cannot remove an observer <_TtC17BMXCircularButton14CircularButton 0x10bd055d0> 
for the key path "highlighted" from <_TtC17BMXCircularButton14CircularButton 0x10bd055d0> because it is not registered as an observer.
 

Это может быть ошибка или я что-то упускаю?

Комментарии:

1. Поскольку он включен self , разве вы не можете просто переопределить свойство и добавить willSet или didSet ?

2. Ниже приведен пример предпочтительного способа сделать это. Я не вижу ничего необычного в вашем коде здесь, как вы создаете экземпляры BMXCircularButton ?

3. Я внезапно вижу это и в objective-c в бета-версии Xcode 7.

Ответ №1:

Как указано Кевином, лучшим ответом здесь действительно является использование didSet и / или willSet в переопределении вашего класса, поскольку вы добавляете наблюдателя в self.

 override var highlighted:Bool {
    didSet {
        // Put your observerValue like code here
    }
}
 

Комментарии:

1. это решение фактически устраняет проблему наблюдения за выделенным атрибутом, но все еще неясно, разрешено ли addObserver / removeObserver в init / deinit .

2. Пожалуйста, обратите внимание, что это не будет работать для NSManagedObjects, потому что они не позволят didSet и willSet