Swift 使用KVO的简单MVVM

Swift 使用KVO的简单MVVM,swift,mvvm,key-value-observing,Swift,Mvvm,Key Value Observing,我正在尝试使用kvo创建一个简单的mvvm模型 我的目标是当UITextField文本更改时,自动更改UILabel文本。 但是由于某些原因,observeValue函数没有被调用 import UIKit class ViewController: UIViewController, UITextFieldDelegate { var viewModel : TestViewModel? @IBOutlet weak var LBLABEL: UILabel! ov

我正在尝试使用kvo创建一个简单的mvvm模型

我的目标是当UITextField文本更改时,自动更改UILabel文本。 但是由于某些原因,
observeValue
函数没有被调用

import UIKit
class ViewController: UIViewController, UITextFieldDelegate {

    var viewModel : TestViewModel?
    @IBOutlet weak var LBLABEL: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel = TestViewModel()

        addObserver(self, forKeyPath: #keyPath(viewModel.infoText), options:  [.old, .new], context: nil)

        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        viewModel?.infoText = textField.text
        return true
    }


    // MARK: - Key-Value Observing
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "info" {
            // Update Time Label
            LBLABEL.text = viewModel?.infoText
        }
    }

}


class TestViewModel : NSObject{
    var model : TestModel

    var infoText:String? {
        didSet{
            model.info = self.infoText

        }
    }

    override init() {
        model = TestModel()
    }
}


class TestModel {
    var info:String?
}

我已经尝试更改观察者的声明,甚至更改ViewModel的获取和设置,但始终没有成功

更新

根据Apple docs的说法,在Swift 4中为关键路径创建观察者要简单得多

class MyObserver: NSObject {
    @objc var objectToObserve: MyObjectToObserve
    var observation: NSKeyValueObservation?

    init(object: MyObjectToObserve) {
        objectToObserve = object
        super.init()

        observation = observe(\.objectToObserve.myDate) { object, change in
            print("Observed a change to \(object.objectToObserve).myDate, updated to: \(object.objectToObserve.myDate)")
        }
    }
}

let observed = MyObjectToObserve()
let observer = MyObserver(object: observed)

observed.updateDate()

您需要将
dynamic
添加到要观察的
NSObject
子类的属性中。就你而言:

@objc dynamic var infoText:String? {
    didSet{
        model.info = self.infoText            
    }
}

顺便说一句,我不知道你为什么要修改textField:shouldChangeCharacters,因为它在更新之前得到了textField值。而且,
keyPath==“info”
永远不会为真。不应该是别的吗。例如,
keyPath==“viewModel.infoText”

您是否在代码中的某个地方添加了
textField.delegate=self
?@Ahmad F-是。在故事板中。我在中的
shouldChangeCharacters上设置了一些断点,代码就停在那里了。模型和viewmodel中字符串的值已正确更改