我有一个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'
}
这样做最优雅的方式是什么?
更新即可。这是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
}
}
答案 0 :(得分:5)
就目前而言,Swift不具备可观察的类属性。 (实际上,静态属性只是全局变量,其命名空间仅限于类中。)
如果要使用KVO,请创建一个具有online
属性的共享实例(单例类),并将观察者添加到实例。
答案 1 :(得分:4)
我用@OOper建议的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" {
// ...
}
}
答案 2 :(得分:2)
尝试将dynamic static var online = false
替换为@nonobjc static var online = false
正在发生的事情是因为它继承自NSObject,Swift正在尝试为它生成getter和setter。因为您是在swift中创建它,所以使用@nonobjc属性可以解决问题。
修改强>
我不相信你可以通过KVO观察静态变量,因为它的工作原理
以下是来自Apple's Guide on KVO
的链接和摘要与使用NSNotificationCenter的通知不同,没有 为所有观察者提供变更通知的中心对象。 相反,通知会在何时直接发送到观察对象 改变了。
也许,您可以在线声明:
,而不是使用KVOstatic var online = false {
didSet{
//code to post notification through regular notification center
}
}
如果您开始使用它,这个问题可能会指向正确的方向 - 它将涉及深入探讨KVO的工作方式:Is it possible to set up KVO notifications for static variables in objective C?
答案 3 :(得分:0)
我建议使用属性包装器,我尝试了下面的示例,并非常适合我:
import React from "react";
import Tick from "./core/Main.js";
//import logo from './logo.svg';
import "./App.css";
function App() {
return (
<div className="App">
<header className="App-header">
<div id="welcome">
<Tick />
</div>
</header>
</div>
);
}
export default App;