我对与关联类型的协议有关,这是在更新到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 }
有人知道为什么会有区别,因为我不明白吗?
答案 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。