双重初始化UIViewController的子类成员在Swift [英] Double Initialization Of UIViewController's Subclass Member in Swift
问题描述
我想创建一个自定义的容器视图控制器,并添加一些成员到 UIViewController
的子类。当我尝试通过使用以下代码从应用程序委托初始化:
self.window = UIWindow(frame:UIScreen.mainScreen ().bounds)
self.window?.rootViewController = CustomContainerViewController()
self.window?.makeKeyAndVisible()
CustomContainerViewController
中的所有成员已初始化两次。
code> CustomContainerViewController 的代码:
class CustomContainerViewController:UIViewController {
let tabBar = CustomTabBar()
override init(){
super.init()
}
必需init(coder aDecoder:NSCoder){
super.init(coder:aDecoder)
}
override init(nibName nibNameOrNil:String ?, bundle nibBundleOrNil:NSBundle?){
super.init :nibNameOrNil ?, bundle:nibBundleOrNil?)
}
}
CustomTabBar
的代码:
class CustomTabBar:UIView {
覆盖init(){
println(init)
super.init()
}
override init(frame:CGRect){
println(initWithFrame :)
super.init(frame:frame)
}
需要init(coder aDecoder:NSCoder){
println(initWithCoder:)
super。 init(coder:aDecoder)
}
}
code> CustomContainerViewController 通过使用前面提到的代码从应用程序委托,总是打印init,initWithFrame两次。
指定的初始化程序使用的不正确。
UIViewController
init(nibName nibNameOrNil:String ?, bundle nibBundleOrNil:NSBundle?)
。
>
指定的初始化程序。如果你子类化UIViewController,你必须调用这个方法的超级实现,即使你没有使用NIB。 (为方便起见,默认的init方法会为你做这个,并为这两个方法参数指定nil。)在指定的NIB中,File's Owner代理应该把它的类设置为你的视图控制器子类,连接到主视图。如果使用nil nib名称调用此方法,则此类'-loadView方法将尝试加载名称与视图控制器类相同的NIB。如果没有这样的NIB实际存在,那么你必须调用-setView:调用-view之前,或者重写-loadView方法以编程设置你的视图。
所以每当你重写 UIViewController
的 init()
UIViewController
的实现将代表你调用 init(nibName nibNameOrNil:String ?, bundle nibBundleOrNil:NSBundle?)
。因此,您的 UIViewController
的子类中的所有成员都初始化了两次。
要解决此问题,请使用以下代码在应用程式委托
self.window = UIWindow(frame:UIScreen.mainScreen()。bounds)
self。 window?.rootViewController = CustomContainerViewController(nibName:nil,bundle:nil)
self.window?.makeKeyAndVisible()
b $ b
不要调用 UIViewController
的 init()
方法或在子类中重载此方法。 / p>
I wanted to make a custom container view controller and added some members to the subclass of UIViewController
. When I try to init it from the app delegate by using following code:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = CustomContainerViewController()
self.window?.makeKeyAndVisible()
all the members in CustomContainerViewController
were initialized twice.
Here is CustomContainerViewController
's code:
class CustomContainerViewController: UIViewController {
let tabBar = CustomTabBar()
override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil?, bundle: nibBundleOrNil?)
}
}
Here is CustomTabBar
's code:
class CustomTabBar: UIView {
override init(){
println("init")
super.init()
}
override init(frame: CGRect) {
println("initWithFrame:")
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
println("initWithCoder:")
super.init(coder: aDecoder)
}
}
Whenever you init the CustomContainerViewController
from the app delegate by using the code previously mentioned, is always prints "init", "initWithFrame" twice.
Incorrect designated initializer used.
UIViewController
has only one designated initializer init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
.
As its comment says
The designated initializer. If you subclass UIViewController, you must call the super implementation of this method, even if you aren't using a NIB. (As a convenience, the default init method will do this for you, and specify nil for both of this methods arguments.) In the specified NIB, the File's Owner proxy should have its class set to your view controller subclass, with the view outlet connected to the main view. If you invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose name is the same as your view controller's class. If no such NIB in fact exists then you must either call -setView: before -view is invoked, or override the -loadView method to set up your views programatically.
So whenever you override the init()
method of UIViewController
, once you call super, UIViewController
's implementation would call init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
on behalf of you. So all the members in your UIViewController
's subclass were initialized twice.
To solve this problem, use following code in the app delegate
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = CustomContainerViewController(nibName: nil, bundle: nil)
self.window?.makeKeyAndVisible()
And never call the init()
method of UIViewController
or override this method in subclasses.
这篇关于双重初始化UIViewController的子类成员在Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!