如何获取引用属性以触发属性观察器?
为了演示我的问题,我编写了一个简单的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()
}
}