我需要声明一个类型为UIView
的变量,该变量也符合MyProtocol
:
protocol MyProtocol: class {
func foobar()
}
class MyClass {
var myView: UIView<MyProtocol>! // Error: Cannot specialize non-generic type 'UIView'
}
但是我遇到编译器错误:无法专用于非通用类型'UIView'。
我需要访问UIView
和MyProtocol
中变量的方法。
支持这些要求的正确的变量声明是什么?
如果有任何不同,则仅UIView
子类将实现该协议。目前,我通过扩展名添加了协议一致性。
我找到了这个答案:https://stackoverflow.com/a/25771265/233602,但尚不清楚该答案是否仍然是在Swift 2中编写时的最佳选择。
使您的班级成为通用类,如下所示,
protocol MyProtocol: class {
func foobar()
}
class MyClass<T:MyProtocol where T:UIView> {
var myView: T!
}
[上面的错误说UIView不能专门用于协议MyProtocol,因此,解决方案是使您的类成为具有遵循MyProtocol且是UIView的子类的通用参数的通用类。
解决此问题的最佳方法可能是使用所有UIViews
都符合的协议:
protocol UIViewType {
var view: UIView { get }
}
extension UIView: UIViewType {
var view: UIView { return self }
}
// the variable
var myView: protocol<UIViewType, MyProtocol>
使用view
属性访问UIView
特定功能。
这里晚些,但是SE-0156(由Swift 4采用)可以在类型声明中启用类和协议的组成,而无需(重新排序为?)泛型。
protocol MyProtocol: class {
func foobar()
}
class MyClass {
var myView: (UIView & MyProtocol)!
}
如果有什么不同,只有UIView子类将实现协议。
这很重要!只需这样做:
protocol MyProtocol: UIView {
func foobar()
}
class MyClass {
var myView: MyProtocol!
}