在类中观察静态var的值?

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)

OOP*_*Per 6

就目前而言,Swift不能具有可观察的类属性。(实际上,静态属性只是全局变量,其名称空间限制在类中。)

如果要使用KVO,请创建一个具有online属性的共享实例(singleton类),并向该实例添加观察者。


MJQ*_*347 5

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)