简体   繁体   English

Swift中UIViewController的子类成员的双重初始化

[英]Double Initialization Of UIViewController's Subclass Member in Swift

I wanted to make a custom container view controller and added some members to the subclass of UIViewController . 我想制作一个自定义的容器视图控制器,并将一些成员添加到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. CustomContainerViewController中的所有成员都初始化了两次。

Here is CustomContainerViewController 's code: 这是CustomContainerViewController的代码:

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: 这是CustomTabBar的代码:

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. 每当您使用前面提到的代码从应用程序委托初始化CustomContainerViewController ,始终会打印两次“ init”,“ initWithFrame”。

Incorrect designated initializer used. 使用了错误的指定初始化器。

UIViewController has only one designated initializer init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) . UIViewController只有一个指定的初始化程序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. 如果您将UIViewController子类化,则即使您未使用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. (为方便起见,默认的init方法将为您执行此操作,并为这两个方法参数都指定nil。)在指定的NIB中,File的Owner代理应将其类设置为您的视图控制器子类,并带有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. 如果您使用nil nib名称调用此方法,则此类的-loadView方法将尝试加载名称与视图控制器类相同的NIB。 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. 如果实际上不存在此类NIB,则必须在调用-view之前调用-setView:,或者重写-loadView方法以编程方式设置视图。

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. 因此,每当您重写UIViewControllerinit()方法时,一旦调用super, UIViewController的实现都将代表您调用init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) So all the members in your UIViewController 's subclass were initialized twice. 因此, UIViewController的子类中的所有成员都初始化了两次。

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. 永远不要调用UIViewControllerinit()方法或在子类中重写此方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM