2017-06-19 64 views
2

我想問一些關於在Swift中進行類型轉換的問題。在從父類創建實例時進行類型轉換

有2個班級。

  1. RootViewController
  2. MyViewController

和類層次結構如下圖所示:

class RootViewController: UIViewController { 

} 

class MyViewController: RootViewController { 

} 

和,我想簡單地調用instance函數來創建從廈門國際銀行文件的實例。 所以我在RootViewController下面實現了函數。

目標C

+ (instancetype)instance { 
    return [[[self class] alloc] initWithNibName:NSStringFromClass([self class]) bundle:nil]; 
} 

夫特

public class func instance<T:RootViewController>() -> T { 
    let type = self as UIViewController.Type 
    let name = NSStringFromClass(type).components(separatedBy: ".").last! 
    let instance = type.init(nibName: name, bundle: nil) 
    return instance as! T 
} 

和,用法是象下面這樣。

Objective-C的

MyViewController *vc = [MyViewController instance]; 

斯威夫特

let vc = MyViewController.instance() as! MyViewController 

問:

我必須一直投實例中使用雨燕的as! MyViewController的類型? 或者有誰能告訴我一個更好的方法在Swift中?

任何幫助,將不勝感激!

+0

我在這裏看不到任何問題或疑問。我個人會避免在swift中使用'instance'或其他工廠方法,因爲你不能使用'Self'作爲返回類型。改爲使用常規的'init'方法。 – kelin

+1

最好使用「as?」而不是「as!」用於鑄造。 –

+0

而且,我必須補充,這個問題最好在https://codereview.stackexchange.com/上提問 – kelin

回答

2
class RootViewController: UIViewController { 
    public class func instance() -> Self { 
     func inner<T: RootViewController>(type: T.Type) -> T { 
      let name = NSStringFromClass(type).components(separatedBy: ".").last! 
      let type1 = type as UIViewController.Type 
      let instance = type1.init(nibName: name, bundle: nil) 
      return instance as! T 
     } 
     return inner(type: self) 
    } 
} 

我建議建立一個擴展方法:

extension UIViewController { 
    public class func instance() -> Self { 
     func inner<T: UIViewController>(type: T.Type) -> T { 
      let name = NSStringFromClass(type).components(separatedBy: ".").last! 
      return T(nibName: name, bundle: nil) 
     } 
     return inner(type: self) 
    } 
} 
+1

這甚至不會編譯。 – kelin

+0

@kelin就好像OP的一樣。 –

+0

@kelin現在檢查。 –

3

你也可以用這樣的方式

let vc:MyViewController = MyViewController.instance() 
0

好了,你可以在這三種方式實例:

  1. 快速推斷到Type

    let myVC = RootViewController.instance() //Swift will automatically infer the type 
    
  2. 明確告訴Type

    let myVC: RootViewController = RootViewController.instance() 
    
  3. 投放到Type

    let myVC = RootViewController.instance() as! RootViewController 
    

所有這三個都是有效的。