I have written a very simple MVC program with a label and a button. The label displays the value of a counter which is incremented when the button is pressed.
The code that follows gives the model file and the view controller file. The model file is a class. That code works.
Here is the model file:
import Foundation
protocol MVCModelDelegate {
var message: String {get set}
}
// when I change class to struct
// delegate is set to nil
// causing the program not to update the label
class Model {
var delegate: MVCModelDelegate?
var counter: Int
var message: String {
didSet {
delegate?.message = model.message
}
}
init(counter: Int, message: String) {
self.counter = counter
self.message = message
}
}
// create instance
var model = Model(counter: 0, message: "")
// counting
func incrementCounter() {
model.counter += 1
model.message = "Counter Value: \(model.counter)"
}
Here is the view controller file
import Cocoa
class ViewController: NSViewController, MVCModelDelegate {
// communication link to the model
var model1 = model
var message = model.message {
didSet {
didUpdateModel(message: message)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.model1.delegate = self
}
// update display
func didUpdateModel(message: String) {
Label1.stringValue = model1.message
}
// Label
@IBOutlet weak var Label1: NSTextField! {
didSet {
Label1.stringValue = " counter not started"
}
}
// Button
@IBAction func testButton(_ sender: NSButton) {
incrementCounter()
}
}
Problem: I now want to change the code of the Model file to use a struct in place of a class as this very simple program does not need all the functionalities of a class. But as soon as I change class for struct. The program still runs, but the label is not updated as the delegate variable is set to nil and never gets another value.
Question: What am I missing? The swift documentation encourages to use struct when possible. And I do not see in that code what could be a problem of transforming the class into a struct.
A struct is immutable and it is not passed by reference like a class, but by value. This means that when you do
var model1 = model
You are creating a copy of model
.
modifying model1
will not propagate the changes to model
, therefore all you do in incrementCounter
is not reflected in your view controller.
If you want your incrementCounter
to affect the viewController it must use the model in your viewController instance.
If your intention is to share the model
properties and change the label value when this model is updated, struct is not the best choice.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.