Swift 4.2 中具有关联类型的协议

Protocols with associated types in Swift 4.2

我有一个关于关联类型协议的问题,发生在更新到 Xcode 10 和 Swift 4.2 之后。

在我有协议之前:

protocol ViewModelBased: class {
    associatedtype ViewModel
    var viewModel: ViewModel { get set }
}

和 VC 实现它。

class MyViewController: UIViewController, ViewModelBased {
    var viewModel: EntitiesViewModel!
}

更新到 Xcode 10 后,我收到错误消息说 MyViewController 不符合协议,我必须将 属性 声明为:

var viewModel: ViewModel! { get set }

任何人都知道为什么会有差异,因为我不明白?

基本上你的代码总是可疑的,现在你被抓了:

protocol ViewModelBased: class {
    associatedtype ViewModel
    var viewModel: ViewModel { get set }
}
class MyViewController: UIViewController, ViewModelBased {
    var viewModel: EntitiesViewModel!
}

在协议采用者MyViewController中,你声称什么类型对应ViewModel?看来你认为它应该是 EntitiesViewModel。并且编译器允许它滑动,允许隐式解包 Optional 包装一个类型来代替类型本身。

但是现在没有隐式展开的 Optional 类型;类型 EntitiesViewModel! 实际上与类型 EntitiesViewModel? 相同,一个可选的包装 EntitiesViewModel。因此,如果您希望 EntitiesViewModel 是 ViewModel,并且如果您希望此 属性 的类型是可选包装 EntitiesViewModel,则协议必须将此 属性 的类型声明为可选包装 ViewModel。