2017-06-19 113 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 
    

所有这三个都是有效的。