第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在Swift中返回instancetype

在Swift中返回instancetype

慕田峪9158850 2019-08-19 14:12:36
在Swift中返回instancetype我正在嘗試進行此擴展:extension UIViewController{     class func initialize(storyboardName: String, storyboardId: String) -> Self     {         let storyboad = UIStoryboard(name: storyboardName, bundle: nil)         let controller = storyboad.instantiateViewControllerWithIdentifier(storyboardId) as! Self         return controller    }}但我得到編譯錯誤:錯誤:無法將'UIViewController'類型的返回表達式轉(zhuǎn)換為返回類型'Self'可能嗎?我也想成為init(storyboardName: String, storyboardId: String)
查看完整描述

3 回答

?
米琪卡哇伊

TA貢獻1998條經(jīng)驗 獲得超6個贊

類似于在Swift中的類擴展函數(shù)中使用'self',您可以定義一個通用的輔助方法,它從調(diào)用上下文中推斷出self的類型:

extension UIViewController{
    class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
    {
        return instantiateFromStoryboardHelper(storyboardName, storyboardId: storyboardId)
    }

    private class func instantiateFromStoryboardHelper<T>(storyboardName: String, storyboardId: String) -> T    {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier(storyboardId) as! T        return controller    }}

然后

let vc = MyViewController.instantiateFromStoryboard("name", storyboardId: "id")

編譯,類型推斷為MyViewController。


Swift 3更新

extension UIViewController{
    class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
    {
        return instantiateFromStoryboardHelper(storyboardName: storyboardName, storyboardId: storyboardId)
    }

    private class func instantiateFromStoryboardHelper<T>(storyboardName: String, storyboardId: String) -> T    {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: storyboardId) as! T        return controller    }}

另一種可能的解決方案,使用unsafeDowncast

extension UIViewController{
    class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
    {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: storyboardId)
        return unsafeDowncast(controller, to: self)
    }}


查看完整回答
反對 回復(fù) 2019-08-19
?
慕森卡

TA貢獻1806條經(jīng)驗 獲得超8個贊

Self是在編譯時確定的,而不是運行時。在你的代碼中,Self完全等同于UIViewController,而不是“恰好調(diào)用它的子類”。這將返回UIViewController,調(diào)用者必須將as它放入正確的子類中。我認為這是你想要避免的(雖然這是“正常的可可”方式,所以只返回UIViewController可能是最好的解決方案)。

注意:initialize在任何情況下都不應(yīng)該命名該函數(shù)。這是現(xiàn)有的類函數(shù),NSObject并且最多會引起混淆,最壞的情況是錯誤。

但是如果你想避免調(diào)用者的話as,子類化通常不是在Swift中添加功能的工具。相反,您通常需要泛型和協(xié)議。在這種情況下,您只需要泛型。

func instantiateViewController<VC: UIViewController>(storyboardName: String, storyboardId: String) -> VC {
    let storyboad = UIStoryboard(name name: storyboardName, bundle: nil)
    let controller = storyboad.instantiateViewControllerWithIdentifier(storyboardId) as! VC    return controller}

這不是一種類方法。這只是一個功能。這里沒有必要上課。

let tvc: UITableViewController = instantiateViewController(name: name, storyboardId: storyboardId)


查看完整回答
反對 回復(fù) 2019-08-19
?
九州編程

TA貢獻1785條經(jīng)驗 獲得超4個贊

更清潔的解決方案(至少在視覺上更整潔):

class func initialize(storyboardName: String, storyboardId: String) -> Self {
    // The absurdity that's Swift's type system. If something is possible to do with two functions, why not let it be just one?    func loadFromImpl<T>() -> T {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        return storyboard.instantiateViewController(withIdentifier: storyboardId).view as! T    }
    return loadFromImpl()}


查看完整回答
反對 回復(fù) 2019-08-19
  • 3 回答
  • 0 關(guān)注
  • 1531 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號