7

我正在尝试使用 RxSwift 在 MVVM 中进行绑定。我有一个Enum

enum Color : Int {
    case Red = 0, Green
}

和考试课

class Test : NSObject {
    var color: Color = .Red
    dynamic var test: String? {
        didSet {
            print("didSet \(test)")
        }
    }
}

并希望观察以下变化:

test.rx_observe(Color.self, "color").subscribeNext { (color) -> Void in
     print("Observer \(color)")
}.addDisposableTo(bag)

但程序与 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<RDProject.Test 0x7ff373513020> addObserver:<RxCocoa.KVOObserver 0x7ff37351a420> forKeyPath:@"color" options:5 context:0x0] was sent to an object that is not KVC-compliant for the "color" property.'

简单String作品的代码:

test.rx_observe(String.self, "test").subscribeNext { string in
     print("Observer \(string)")
}.addDisposableTo(bag)

test.test = "1"
test.test = "2"

我在这里发现,要让类不是从我那里继承的,NSObject我应该让它dynamic,但我不能让它成为Enum动态的。有没有办法让Enumobservable?

4

3 回答 3

5

您不需要为此任务使用 KVO。只需使用这样的 BehaviorSubject :

创建一个像这样的私有字段:

let colorSubject = BehaviorSubject<Color?>(value: nil)

然后你有一个像这样的属性,它通知 BehaviorSubject 值确实发生了变化。

var color : Color? {
    didSet {
        colorSubject.onNext(color)
    }
}

要订阅任何更改,请使用与此等效的语句:

let disposable = colorSubject.subscribeNext { (color: Color?) -> Void in
    // Do something with it.
}
于 2016-03-16T10:26:24.003 回答
2

因为你的 enum 是 type Int,你可以通过标记它使其与 Objective-c 兼容@objc。这样做将使编译器可以将属性标记为dynamic. 要使该属性符合 KVO,还需要使用@objc.

@objc enum Color : Int {
    case Red = 0, Green
}

class Test : NSObject {
    @objc dynamic var color: Color = .Red
    dynamic var test: String? {
        didSet {
            print("didSet \(test)")
        }
    }
}
于 2016-03-16T10:01:57.777 回答
0

我可以建议只制作一个代理变量并在其上使用 KVO。

class Model: NSObject {

    enum Color: Int {
        case Red = 0, Green
    }

    dynamic var colorRaw: Int?
    var color: Color = .Red {
        didSet {
            colorRaw = color.rawValue
        }
    }

}

更多细节在这里 - https://christiantietze.de/posts/2015/05/observing-enum-swift-kvo/

于 2016-03-16T09:42:42.280 回答