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

时间:2018-10-08 10:36:24

标签: swift-protocols swift4.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 }

有人知道为什么会有区别,因为我不明白吗?

1 个答案:

答案 0 :(得分:1)

基本上,您的代码始终是可疑的,现在您已被抓住:

SELECT o.orderNumber, 
       o.status, 
       SUM(od.quantity * od.price) AS total   
FROM order AS o 
JOIN orderDetail AS od ON o.orderNumber = od.orderNumber 
WHERE o.status = 'shipped' 
GROUP BY o.orderNumber, o.status 
HAVING total > 1500 
ORDER BY totalEach DESC 

在协议采用者MyViewController中,您声称与ViewModel对应的是哪种类型?看来您认为应该是EntitiesViewModel。并且编译器允许它滑动,从而允许隐式解开的Optional包装类型来替换类型本身。

但是现在没有隐式解包的Optional类型;类型protocol ViewModelBased: class { associatedtype ViewModel var viewModel: ViewModel { get set } } class MyViewController: UIViewController, ViewModelBased { var viewModel: EntitiesViewModel! } 实际上与类型EntitiesViewModel!相同,后者是一个可选的包装EntitiesViewModel。因此,如果您希望EntitiesViewModel为ViewModel,并且希望将此属性的类型为Optional包装的EntitiesViewModel,则协议必须将该属性的类型声明为Optional包装的ViewModel。