可选的结合,不论泛型类型
问题描述:
考虑下面的代码片段:可选的结合,不论泛型类型
通用的Web包装视图控制器的定义:
class WebWrapperViewController<T where T: UIView, T: WebViewCommon>: UIViewController, UIWebViewDelegate, WKNavigationDelegate {
var loginUrl: NSURL!
var webView: T!
// ...
}
代码在AppDelegate中:
var webWrapperVC: UIViewController
if #available(iOS 8.0, *) {
webWrapperVC = WebWrapperViewController<WKWebView>()
} else {
webWrapperVC = WebWrapperViewController<UIWebView>()
}
if let wvc = webWrapperVC as? WebWrapperViewController { // compiler error
// don't care what generic type of WebWrapperViewController was created in here
wvc.loginUrl = NSURL(string: "https://foo")
}
我得到以下编译器错误的可选绑定:
参数为泛型参数“T”不能推断
我不在乎已创建什么类型的WebWrapperViewController
通用版本,所以我不想让施放任何更具体。
有谁知道如何通配符投给任何泛型类型?
我已经试过:
if let wvc = webWrapperVC as? WebWrapperViewController<AnyObject>
...有一堆尖括号内的其他东西,包括<UIView>
,<*>
,<T>
一起。等
答
可能解决这个最好的方法是使用一个协议,其中所有UIViews
符合的,而不是一个泛型类,因为泛型铸造不完全支持:
protocol UIViewType {
var view: UIView { get }
}
extension UIView: UIViewType {
var view: UIView { return self }
}
// the variable
var webView: protocol<UIViewType, WebViewCommon>
使用视图属性来访问UIView特定的功能。
另一种方法是使一个failable初始化这需要一个WebWrapperViewController
和失败,如果泛型类型不能铸造:
class WebWrapperViewController<T where T: UIView, T: WebViewCommon>: UIViewController, UIWebViewDelegate, WKNavigationDelegate {
var loginUrl: NSURL!
var webView: T!
init?<U>(wwvc: WebWrapperViewController<U>) {
// assign all variables
if let webView = wwvc.webView as? T {
self.webView = webView
} else {
return nil
}
loginUrl = wwvc.loginUrl
}
}
// Now you can use it like this
if let wvc = WebWrapperViewController<AnyObject>(wwvc: webWrapperVC) {
wvc.loginUrl = NSURL(string: "https://foo")
}