2015-10-14 48 views
0

我正在寫動態使用最合適的web視圖類取決於它在其上運行的IOS版本的web包裝視圖控制器:在夫特聲明特異性通用類型的變量獨立2

protocol WebViewCommon: class { 
    func loadURL(url: NSURL) 
    func disableBouncing() 
    func haveLoadedPage() -> Bool 
} 

class WebWrapperViewController<T where T: UIView, T: WebViewCommon>: UIViewController { 

    var loginUrl: NSURL! 
    var webView: T! 

    // ... 
} 

然後我需要實例正確的通用版本如下:

var webWrapperVC: WebWrapperViewController // compiler error 

    if #available(iOS 8.0, *) { 
     webWrapperVC = WebWrapperViewController<WKWebView>() 
    } else { 
     webWrapperVC = WebWrapperViewController<UIWebView>() 
    } 

    webWrapperVC.loginUrl = targetURL // access WebWrapperViewController specific API 
    self.window!.rootViewController = webWrapperVC 

var聲明沒有編制,並出現以下錯誤:

Reference to generic type 'WebWrapperViewController' requires arguments in <...>

到目前爲止,我曾嘗試:

var webWrapperVC: WebWrapperViewController<UIView<WebViewCommon>> 

(這會導致 「類型 '的UIView' 不符合協議 'WebViewCommon'」)

var webWrapperVC: WebWrapperViewController<T where T: UIView, T: WebViewCommon> 

(其結果是:「預期'>'完成通用參數列表」)

我的問題是因此:在這種情況下,正確的var聲明是什麼?由於我需要訪問特定於WebWrapperViewController的API,因此var聲明需要包含此類型。

+1

爲什麼不可選? var webWrapperVC:WebWrapperViewController? – dirtydanee

+0

因爲我正在使用'if-else'語句,變量肯定會被初始化。事實上,甚至有效的Swift在這裏聲明爲「let」。 並聲明爲可選不會導致編譯器錯誤消失。 –

回答

0

我不認爲你需要在這種情況下使用泛型。你有一個協議來代替。定義沒有泛型的視圖控制器,並使用該協議作爲webView的類型。

class WebWrapperViewController: UIViewController { 

    var loginUrl: NSURL? 
    var webView: WebViewCommon? 

    // ... 
} 
+0

然後我得到這個編譯器錯誤:'WebWrapperViewController'要求'WebViewCommon'從'UIView'繼承,這就是爲什麼我也試過'var webWrapperVC:WebWrapperViewController >' –

+0

如果這是在'WebWrapperViewController'中,那麼: 'var webWrapperVC:WebWrapperViewController ' –

+0

對不起 - 這是在'UIApplicationDelegate'子類中。我嘗試將「通用版本」的邏輯移植到「WebWrapperViewController」中的靜態工廠方法中,但遇到與該函數的返回類型完全相同的問題,並且「WebWrapperViewController 」沒有涉及它。 –