无论通用类型

时间:2015-10-14 16:25:11

标签: swift generics swift2 optional

请考虑以下代码段:

通用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>。等

1 个答案:

答案 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")
}