引用属性上的 swift 属性观察器



如何获取引用属性以触发属性观察器?

为了演示我的问题,我编写了一个简单的MVC程序,只有一个按钮和一个标签。该按钮递增模型中的计数器,并在视图控制器的标签中显示计数器的值。

问题是计数器增量(在模型中(不会触发didSet观察器(在视图控制器中(

下面是模型文件:

import Foundation
class MvcModel {
    var counter: Int
    var message: String
    init(counter: Int, message: String) {
        self.counter = counter
        self.message = message
    }
}
// create instance
var model = MvcModel(counter: 0, message: "" )
// counting
func incrementCounter() {
    model.counter += 1
    model.message = "Counter Value:  (model.counter)"
    //print(model.message)
}

下面是视图控制器文件:

import Cocoa
class ViewController: NSViewController {
    let model1 = model
    var messageFromModel = model.message {
        didSet {
            updateDisplayCounterLabel()
        }
    }
    // update Label
    func updateDisplayCounterLabel() {
        DisplayCounterLabel.stringValue = model1.message
    }
    // Label
    @IBOutlet weak var DisplayCounterLabel: NSTextField! {
        didSet {
            DisplayCounterLabel.stringValue = "counter not started"
        }
    }
    // Button
    @IBAction func IncrementButton(_ sender: NSButton) {
        incrementCounter()
        print("IBAction:  (model1.message)")
    }
}

我想问题与引用属性有关(因为我已经能够使该程序与基于结构的模型一起工作(。

如果有人能告诉我如何处理属性观察器和引用属性并使这种 MVC 工作,因为我计划在实际程序中使用它,我将不胜感激。

您可以

MvcModel创建一个委托

protocol MvcModelDelegate {
    func didUpdateModel(counter:Int)
}

接下来,将委托属性添加到MvcModel

class MvcModel {
    var counter: Int {
        didSet {
            delegate?.didUpdateModel(counter: counter)
        }
    }
    var message: String
    var delegate: MvcModelDelegate?
    init(counter: Int, message: String) {
        self.counter = counter
        self.message = message
    }
}

然后你使ViewController类符合MvcModelDelegate最后你model.delegate = self设置到viewDidLoad

class Controller: UIViewController, MvcModelDelegate {
    let model = MvcModel(counter: 0, message: "hello")
    override func viewDidLoad() {
        super.viewDidLoad()
        self.model.delegate = self
    }
    func didUpdateModel(counter: Int) {
        print("new value for counter (counter)")
    }
}

如果有人对这里感兴趣,这里是Noam建议的代码。

模型文件:

    import Foundation
    protocol MvcModelDelegate {
        func didUpDateModel(message: String)
    }
    class MvcModel {
        var counter: Int
        var message: String {
            didSet {
                delegate?.didUpDateModel(message: message)
            }
        }
        var delegate: MvcModelDelegate?
        init(counter: Int, message: String) {
            self.counter = counter
            self.message = message
        }
    }
    // create instance
    var model = MvcModel(counter: 0, message: "" )
    // counting
    func incrementCounter() {
        model.counter += 1
        model.message = "Counter Value:  (model.counter)"
    }
}

查看控制器文件

import Cocoa
class ViewController: NSViewController, ModelDelegate {
    // communication link to the model
    var model1 = model
    var messageFromModel = messageToLabel
    override func viewDidLoad() {
        super.viewDidLoad()
        self.model1.delegate = self
    }
    // update display
    func didUpdateModel(message: String) {
        //self.Label1.stringValue = model1.message
        self.Label1.stringValue = messageFromModel
    }
    // Label
    @IBOutlet weak var Label1: NSTextField! {
        didSet {
            Label1.stringValue = " counter not started"
        }
    }
    // Button
    @IBAction func testButton(_ sender: NSButton) {
        incrementCounter()
    }    
}

最新更新