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

时间:2014-10-11 03:32:12

标签: ios cocoa-touch swift

我想创建一个自定义容器视图控制器,并将一些成员添加到UIViewController的子类中。当我尝试使用以下代码从app delegate初始化它时:

self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = CustomContainerViewController()
self.window?.makeKeyAndVisible()

CustomContainerViewController中的所有成员都被初始化了两次。

以下是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?)
    }
}

以下是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)
    }
}

每当你使用前面提到的代码从app delegate初始化CustomContainerViewController时,总是会打印“init”,“initWithFrame”两次。

1 个答案:

答案 0 :(得分:5)

使用了错误的指定初始值设定项。

UIViewController只有一个指定的初始化程序init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)

正如其评论所说

  

指定的初始化程序。如果你是UIViewController的子类,你必须调用这个方法的超级实现,即使你没有使用NIB。 (为方便起见,默认的init方法将为您执行此操作,并为这两个方法参数指定nil。)在指定的NIB中,File的所有者代理应将其类设置为视图控制器子类,视图插座连接到主视图。如果使用nil nib名称调用此方法,则此类' -loadView方法将尝试加载名称与视图控制器类相同的NIB。如果事实上不存在这样的NIB,则必须在调用-view之前调用-setView:或覆盖-loadView方法以编程方式设置视图。

因此,无论何时覆盖init()的{​​{1}}方法,一旦您拨打超级用户,UIViewController的实施方式将代表您致电UIViewController。因此,init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)子类中的所有成员都被初始化了两次。

要解决此问题,请在app delegate

中使用以下代码
UIViewController

永远不要调用self.window = UIWindow(frame: UIScreen.mainScreen().bounds) self.window?.rootViewController = CustomContainerViewController(nibName: nil, bundle: nil) self.window?.makeKeyAndVisible() 的{​​{1}}方法或在子类中覆盖此方法。