简体   繁体   中英

Swift: how to change a class into a struct

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM