观察类中静态variables的值?
我有一个静态的类,其中存储当前的在线连接状态的类。 我想通过其他类来观察ConnectionManager.online
的值。 我想用KVO
做到这一点,但声明一个static
variables为dynamic
导致一个错误:
class ConnectionManager: NSObject { dynamic static var online = false // adding 'dynamic' declaration causes error: // "A declaration cannot be both 'final' and 'dynamic' }
什么是最优雅的方式呢?
编辑:
这是我的代码为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 } }
至于现在,Swift不能有可观察的类属性。 (事实上,静态属性只是全局variables,其名称空间被限制在一个类中。)
如果您想使用KVO,请创build一个具有online
属性的共享实例(单例类),并将观察者添加到该实例。
尝试replacedynamic static var online = false
到@nonobjc static var online = false
发生什么事是因为它从NSObjectinheritance,Swift正试图为它生成getter和setter。 因为您正在快速创build它,所以使用@nonobjc属性可以解决问题。
编辑:
我不相信你可以通过KVO观察静态variables,因为它是如何工作的
这里是苹果的KVO指南的链接和片段
与使用NSNotificationCenter的通知不同,不存在为所有观察者提供更改通知的中央对象。 而是在发生更改时直接将通知发送到观察对象。
也许,而不是使用KVO,你可以在线声明如下:
static var online = false { didSet{ //code to post notification through regular notification center } }
如果你开始使用它,这个问题可能会指向你正确的方向 – 它将涉及更深入地了解KVO的工作原理: 是否可以在目标C中为静态variables设置KVO通知?
我用@OOperbuild议的singleton
模式解决了这个问题。
class ConnectionManager: NSObject { static let sharedInstance = ConnectionManager() private override init() {} // This prevents others from using the default '()' initializer for this class. dynamic var online = false }
然后:
override func viewDidLoad() { super.viewDidLoad() self.tableView.tableFooterView = UIView() ConnectionManager.sharedInstance.addObserver(self, forKeyPath: "online", options: NSKeyValueObservingOptions(), context: nil) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { if object is ConnectionManager && keyPath == "online" { // ... } }