MJQ*_*347 4 cocoa-touch key-value-observing class-variables ios swift
我有一门课,static var其中存储了当前的在线连接状态。我想ConnectionManager.online通过其他课程来观察价值。我想用KVO做到这一点,但是将static变量声明为dynamic会导致错误:
class ConnectionManager: NSObject {
dynamic static var online = false
// adding 'dynamic' declaration causes error:
// "A declaration cannot be both 'final' and 'dynamic'
}
Run Code Online (Sandbox Code Playgroud)
最优雅的方法是什么?
更新。这是我的KVO部分代码:
override func viewDidLoad() {
super.viewDidLoad()
ConnectionManager.addObserver(
self,
forKeyPath: "online",
options: NSKeyValueObservingOptions(),
context: nil
)
}
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?,
change: [String : AnyObject]?,
context: UnsafeMutablePointer<Void>) {
if keyPath == "online" {
print("online status changed to: \(ConnectionManager.online)")
// doesn't get printed on value changes
}
}
Run Code Online (Sandbox Code Playgroud)
就目前而言,Swift不能具有可观察的类属性。(实际上,静态属性只是全局变量,其名称空间限制在类中。)
如果要使用KVO,请创建一个具有online属性的共享实例(singleton类),并向该实例添加观察者。
我singleton用@OOper 建议的模式解决了它。
class ConnectionManager: NSObject {
static let sharedInstance = ConnectionManager()
private override init() {} // This prevents others from using the default '()' initializer for this class.
@objc dynamic var online = false
}
Run Code Online (Sandbox Code Playgroud)
然后:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.tableFooterView = UIView()
ConnectionManager.sharedInstance.addObserver(self,
forKeyPath: "online",
options: [.new, .initial],
context: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if object is ConnectionManager && keyPath == "online" {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)