请考虑以下代码段:
通用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>
。等
答案 0 :(得分:0)
解决此问题的最佳方法可能是使用一个所有UIViews
符合而不是泛型类的协议,因为不完全支持使用泛型进行转换:
protocol UIViewType {
var view: UIView { get }
}
extension UIView: UIViewType {
var view: UIView { return self }
}
// the variable
var webView: protocol<UIViewType, WebViewCommon>
使用view属性访问UIView特定功能。
另一种方法是创建一个可用的初始值设定项,它接受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")
}