【发布时间】:2018-09-27 07:52:15
【问题描述】:
我是从 Objective-C 来到 Swift 的,Objective-C 可以做很多事情,但 Swift 要复杂得多。比如OOP动态初始化器。
例如我有这段代码在 Objective-C 中工作:
@interface CommonVC: UIViewController
+ (instancetype)showFrom:(UIViewController *)vc;
@end
@implementation CommonVC
+ (instancetype)showFrom:(UIViewController *)vc {
CommonVC *instance = [self instantiateFrom:vc.nibBundle];
[vc presentViewController:instance animated:YES completion:nil];
return instance;
}
// this is like convenience initializer.
+ (instancetype)instantiateFrom:(NSBundle *)aBundle {
return [self.alloc initWithNibName:NSStringFromClass(self.class) bundle:aBundle];
}
@end
@interface SubClassVC: CommonVC
@end
然后像这样使用子类或超类:
SubClassVC *subVC = [SubClassVC showFrom:self];
// or in swift:
SubClassVC.show(from: self)
但是,在 swift 中,似乎不可能实现这样的东西。我尝试了一些,但总是出现编译错误。这是一个:
class CommonVC: UIViewController {
class func show(from sender: UIViewController) -> Self {
let vc = self(sender: sender) // Compiler error: Constructing an object of class type 'Self' with a metatype value must use a 'required' initializer
sender.present(vc, animated: true, completion: nil)
return unsafeDowncast(vc, to: self)
}
convenience init(sender: UIViewController) {
self.init(nibName: type(of: self).className, bundle: sender.nibBundle)
loadView()
}
}
那么我如何从超类编写 viewController 的通用便利初始化程序,然后用子类调用它?
当然,我的便利 init 有很多东西,我只是简化为这个简单的代码,而且函数 show(from:) 有不同的表示,而不是这个简单的 present(_:animated:completion:)。
即使我在初始化后创建一个函数来进行设置,它仍然无法工作
class CommonVC: UIViewController {
class func show(from sender: UIViewController) -> Self {
let vc = self.init(nibName: type(of: self).className, bundle: sender.nibBundle) // Compiler error: Constructing an object of class type 'Self' with a metatype value must use a 'required' initializer
vc.setupAfterInitialize()
sender.present(vc, animated: true, completion: nil)
return unsafeDowncast(vc, to: self)
}
convenience init(sender: UIViewController) {
self.init(nibName: type(of: self).className, bundle: sender.nibBundle)
setupAfterInitialize()
}
internal func setupAfterInitialize() {
// do stuff
loadView()
}
}
而且代码看起来很愚蠢,不能方便地初始化convenience。
目前,我不能使用类函数show(from:),但将演示文稿移到外面并进行如下操作:
CommonVC.show(from: self)
SubClassVC(sender: self).present()
// instead of this simple presentation:
// SubClassVC.show(from: self)
我什至试过了,但还是不行:
class func show<T: CommonVC>(from sender: UIViewController) -> Self {
T.init(nibName: type(of: self).className, bundle: sender.nibBundle)
....
【问题讨论】:
-
是的,你的就是我得到
-> Self和unsafedowncast(vc, to: self)的地方。我会尝试更多地闲逛......
标签: objective-c swift oop inheritance initialization