2015-10-14 38 views
0

考虑下面的代码片段:可选的结合,不论泛型类型

通用的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

可能解决这个最好的方法是使用一个协议,其中所有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") 
}