在类中观察静态var的值?

时间:2016-07-06 22:34:09

标签: ios swift cocoa-touch key-value-observing class-variables

我有一个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
    }
}

4 个答案:

答案 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的通知不同,没有   为所有观察者提供变更通知的中心对象。   相反,通知会在何时直接发送到观察对象   改变了。

也许,您可以在线声明:

,而不是使用KVO
static 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;