Странное поведение наблюдения ключ-значение
Возможно, этот вопрос носит более общий характер, чем мне кажется, но я хотел убедиться, что я показал свой полный контекст на случай, если что-то есть причина этой проблемы.
- Я написал одноэлементный класс с KVC-совместимым свойством и двумя методами:
class Singleton: NSObject {
static let sharedInstance = Singleton()
@objc dynamic var aProperty = false
func updateDoesntWork() {
aProperty = !aProperty
}
func updateDoesWork() {
Singleton.sharedInstance.aProperty = !aProperty
}
}
- Я добавляю наблюдателя для свойства в установочный код моего делегата приложения:
Singleton.sharedInstance.addObserver(self, forKeyPath: #keyPath(Singleton.aProperty), options: [.new], context: nil)
- Я отменяю делегат моего приложения
observeValue()
метод:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
NSLog("observeValue(forKeyPath: \(String(describing:keyPath)), of: \(String(describing:object)), change: \(String(describing:change)), context:\(String(describing:context)))")
}
Теперь, если я позвоню Singleton.sharedInstance.updateDoesntWork()
Я не получаю запись в журнале изменений в aProperty
, Свойство изменено (я проверял это в отладчике), просто уведомление не отправляется.
Тогда как, если я позвоню Singleton.sharedInstance.updateDoesWork()
все работает так, как я и ожидал - свойство тоже, конечно, меняется, но самое главное, на этот раз наблюдатель уведомляется об изменении (запись в журнале печатается).
Для меня нет смысла, что мне нужно полное Singleton.sharedInstance.aProperty
а не просто aProperty
для КВО работать. Что мне не хватает?
1 ответ
Я предполагаю, что у вас есть проблемы, чтобы использовать "var" для синглтона. Вы можете рассмотреть возможность использования следующего фрагмента для создания синглтона и инициализации некоторых значений, включая наблюдение, используемое исключительно синглтоном:
class Singleton: NSObject {
static private var sharedInstanceObserver : NSKeyValueObservation!
static let sharedInstance: Singleton = {
let sInstance = Singleton()
sharedInstanceObserver = sInstance.observe(\Singleton.aProperty, options: NSKeyValueObservingOptions.new, changeHandler: { st, value in
print (st)
print(value)
})
return sInstance
}()
@objc dynamic var aProperty = false
func updateDoesntWork() {
aProperty = !aProperty
}
func updateDoesWork() {
Singleton.sharedInstance.aProperty = !aProperty
}
}