双重初始化UIViewController的子类成员在Swift [英] Double Initialization Of UIViewController's Subclass Member in Swift

查看:163
本文介绍了双重初始化UIViewController的子类成员在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆