Swift:如何将类更改为结构

时间:2017-07-04 15:00:24

标签: swift class model-view-controller struct

我写了一个非常简单的MVC程序,带有标签和按钮。标签显示计数器的值,按下按钮时该计数器会递增。

下面的代码给出了模型文件和视图控制器文件。模型文件是一个类。 该代码有效。

这是模型文件:

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)"
}

这是视图控制器文件

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()
    }
}

问题:我现在想要更改模型文件的代码以使用结构代替类,因为这个非常简单的程序不需要类的所有功能。但是一旦我改变了struct的类。该程序仍然运行,但标签未更新,因为委托变量设置为nil并且永远不会获得另一个值。

问题:我错过了什么? swift文档鼓励尽可能使用struct。我没有在代码中看到将类转换为结构的问题。

1 个答案:

答案 0 :(得分:2)

结构是不可变的,它不像类一样通过引用传递,而是通过值传递。这意味着当你做

var model1 = model

您正在创建model的副本。

修改model1不会将更改传播到model,因此您在incrementCounter中所做的一切都不会反映在您的视图控制器中。

如果您希望incrementCounter影响viewController,它必须使用viewController实例中的模型。

如果您打算在更新此模型时共享model属性并更改标签值,那么struct不是最佳选择。