我的问题是,是否可以在Swift上的Singleton属性上使用KVC。我在测试一个类上的KVC,它能够工作,但是决定看看它是否能在Singleton类上工作。
我遇到一个错误,说明我的Singleton的“共享”属性不兼容KVC。
class KVOObject: NSObject {
@objc static let shared = KVOObject()
private override init(){}
@objc dynamic var fontSize = 18
}
override func viewDidLoad() {
super.viewDidLoad()
addObserver(self, forKeyPath: #keyPath(KVOObject.shared.fontSize), options: [.old, .new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(KVOObject.shared.fontSize) {
// do something
}
}我目前正在收到以下错误:
NetworkCollectionTest9714 Test9714:452848*终止应用程序,原因是:‘addObserver: forKeyPath:@shared.fontSize“选项:3上下文:0x0被发送到一个不符合KVC的对象,该对象与”共享“属性不兼容。
发布于 2017-12-06 02:20:39
关键路径不正确。我是KVOObject.fontSize。你需要把观察者添加到这个单例中:
KVOObject.shared.addObserver(self, forKeyPath: #keyPath(KVOObject.fontSize), options: [.old, .new], context: nil)另外,(a)您可能应该使用上下文来确定您是否正在处理这个问题,或者它是否可能被超类使用;(b)如果super实现不是您的,则应该调用它;以及(c)确保删除deinit上的观察者
class ViewController: UICollectionViewController {
private var observerContext = 0
override func viewDidLoad() {
super.viewDidLoad()
KVOObject.shared.addObserver(self, forKeyPath: #keyPath(KVOObject.fontSize), options: [.new, .old], context: &observerContext)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &observerContext {
// do something
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
deinit {
KVOObject.shared.removeObserver(self, forKeyPath: #keyPath(KVOObject.fontSize))
}
...
}或者,如果在Swift 4中,它现在要容易得多,因为它基于闭包(避免对上下文的需要),并在NSKeyValueObservation超出范围时自动删除:
class ViewController: UICollectionViewController {
private var token: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
token = KVOObject.shared.observe(\.fontSize, options: [.new, .old]) { [weak self] object, change in
// do something
}
}
...
}顺便提一下,一些关于单身人士的观察:
shared属性不需要@objc限定符;只有要观察的属性才需要;以及init方法确实应该调用super;以及final,以避免可能导致子类化的混淆。因此:
final class KVOObject: NSObject {
static let shared = KVOObject()
override private init() { super.init() }
@objc dynamic var fontSize: Int = 18
}https://stackoverflow.com/questions/47665612
复制相似问题