Reputation: 2968
I would like to ask something about type-casting in Swift.
There are 2 classes.
RootViewController
MyViewController
and the class hierarchy is like below:
class RootViewController: UIViewController {
}
class MyViewController: RootViewController {
}
and, I want to simply call instance
function to create an instance from xib file.
so I implemented below function in RootViewController
.
Objective-C
+ (instancetype)instance {
return [[[self class] alloc] initWithNibName:NSStringFromClass([self class]) bundle:nil];
}
Swift
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
}
and, usage is like below.
Objective-C
MyViewController *vc = [MyViewController instance];
Swift
let vc = MyViewController.instance() as! MyViewController
Question:
Do I have to always cast the type of instance using as! MyViewController
in Swift?
Or can anybody advise me a better approach in Swift?
Any help would be appreciated!
Upvotes: 2
Views: 266
Reputation: 10050
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)
}
}
I would suggest creating an extension method:
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)
}
}
Upvotes: 2
Reputation: 7585
Okay you can instantiate in these three ways:
Swift inference to Type
:
let myVC = RootViewController.instance() //Swift will automatically infer the type
Explicitly telling the Type
:
let myVC: RootViewController = RootViewController.instance()
Casting to your Type
:
let myVC = RootViewController.instance() as! RootViewController
All these three are valid.
Upvotes: 0
Reputation: 1789
You can Also use like this way
let vc:MyViewController = MyViewController.instance()
Upvotes: 3