如何快速将对象引用更改为已实现相同协议的新对象?

问题描述

我想要一个全局设置模型并在运行时进行更改。不幸的是,我的视图模型拥有旧的全局设置模型的参考。我的复杂解决方案是使用新的设置模型再次更新所有视图模型。有更好的解决方案吗?这是我的示例代码不起作用。我的意图是第三个输出是“英寸”。

protocol SettingsModelProtocol {
    var unit: String { get set }
}

class MetricSettingsModel: SettingsModelProtocol {
    var unit: String = "cm"
}

class ImperialSettingsModel: SettingsModelProtocol {
    var unit: String = "Inch"
}

class viewmodel {
    var settingsModel: SettingsModelProtocol?
    var unit: String {
        settingsModel?.unit ?? "--"
    }
}

var globalSettingsModel: SettingsModelProtocol = MetricSettingsModel()

var viewmodel = viewmodel()
print(viewmodel.unit)
viewmodel.settingsModel = globalSettingsModel
print(viewmodel.unit)
globalSettingsModel = ImperialSettingsModel()
print(viewmodel.unit)
viewmodel.settingsModel = globalSettingsModel
print(viewmodel.unit)

输出

  1. -
  2. cm
  3. cm
  4. 英寸

解决方法

在viewModel和settingsModel之间放置另一层。就像settingsService一样,每个viewModel都将引用相同的服务,并且当您要更改设置模型时,可以在settingsService中进行设置,该服务将设置模型提供给viewModel。

settingsService.settingsModel = globalSettingsModel

class ViewModel {
    var settingsService: SettingsServiceProtocol?
    var unit: String {
        settingsService?.settingsModel.unit ?? "--"
    }
}