Add final
这里的解决方案只是添加final
到子类UIViewController
(在我的例子中,它是CameraViewController
).
这允许您的调用站点正确推断出类型UIViewController
无需铸造。在我的示例中,调用站点是:
guard let controller = CameraViewController.instantiate() else {
return
}
但为什么?
为什么添加最终关键字很重要?
与大家讨论后@阿里软件 https://stackoverflow.com/users/803787/alisoftware,他解释了需要final
。 (他还在 Swift mixin 存储库中添加了一个类似的协议,Reusable https://github.com/AliSoftware/Reusable.)
编译器关心你的自定义 VC 是否是final
以确保Self
要求Instantiatable
提及项可以静态推断,也可以不静态推断。
在一个例子中:
class ParentVC: UIViewController, Instantiatable {
// Because of Instantiatable, this class automatically has a method
// with this signature:
func instantiate() -> ParentVC // here, the "Self" coming from the Protocol, meaning "the conforming class", which is solved as "ParentVC"
}
class ChildVC: ParentVC {
// Error: It inherits from ParentVC, and has to conform
// to Instantiatable as a Parent
func instantiate() -> ParentVC
// but, it also has this from being a Instantiatable object itself
func instantiate() -> ChildVC
// thus, the compiler cannot solve what "Self" should resolve to here,
// either ParentVC or ChildVC.
//
// Also, it can generate problems in various contexts being "of
// both types" here, which is why it's not permitted
}
为什么添加final就可以了
您的自定义 VC 直接继承自UIViewController
,但不需要进一步子类化,所以你应该标记它final
anyway.
或者,您正在创建父摘要CommonVC
。您打算生育多个孩子(class CustomVC1: CommonVC
, class CustomVC2: CommonVC
),继承它,但在这种情况下CommonVC
是抽象的,可能不会直接实例化。因此,它不是被标记为的那个Instantiatable
,并且您应该标记CustomVC1
等等,你打算实例化为final
+ Instantiatable
反而。