我想在watchOS,iOS和TvOS上创建一个视图协议,所以我可以通用的方式获取他们的子视图和超级视图。
起初我试过这个:
protocol ViewProtocol: Hashable {
var superview: Self? { get }
var subviews: [Self] { get }
}
然后我像这样扩展UIView
类:
extension UIView: ViewProtocol {}
但是我从编译器中得到了这个错误:
<unknown>:0: error: protocol 'ViewProtocol' requirement 'superview' cannot be satisfied by a non-final class ('UIView') because it uses 'Self' in a non-parameter, non-result type position
我不能理解这个问题(我认为这与编译器无法在非最终类中使用Self有关),所以我尝试了以下内容:
协议如下所示:
protocol ViewProtocol: Hashable {
func getSuperview() -> ViewProtocol?
func getSubviews() -> [ViewProtocol]
}
但是现在我在协议声明中得到了这个错误:
Protocol 'ViewProtocol' can only be used as a generic constraint because it has Self or associated type requirements
所以我尝试了这个:
protocol ViewProtocol: Hashable {
func getSuperview<T: ViewProtocol>() -> T?
func getSubviews<T: ViewProtocol>() -> [T]
}
实现看起来像这样:
extension UIView: ViewProtocol {
func getSuperview<T>() -> T? where T : ViewProtocol {
return self.superview as! T?
}
func getSubviews<T>() -> [T] where T : ViewProtocol {
return self.subviews as! [T]
}
}
但是现在当我尝试在泛型类型ViewProtocol
上使用该方法时,我收到此错误:Generic parameter 'T' could not be inferred
有人能帮助我吗?我想从根本上理解这里发生了什么以及为什么要这么做很难?
答案 0 :(得分:1)
在非最终课程中你不能有Self
的要求,这里有一个例子来说明为什么这没有意义:
protocol Copyable {
var copyOfSelf: Self { get }
}
final class Car {
let name: String
init(name: String) { self.name = name }
}
extension Car: Copyable {
var copyOfSelf: Car { return Car(name: self.name) }
}
class SportsCar: Car {
// Inherited:
// var copyOfSelf: Car { return Car(name: self.name) }
// Notice that it still returns `Car`, not `SportsCar`,
// Breaking the conformance to `Copyable`
}