如何获取引用属性以触发属性观察者?
为了演示我的问题,我用一个按钮和一个标签编写了一个简单的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工作,我会很感激,因为我计划在真实程序中使用它。
答案 0 :(得分:1)
您可以为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)")
}
}
答案 1 :(得分:1)
如果有人对此感兴趣,请使用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()
}
}