编辑:这是Xcode 6.4的完整代码示例
我有一个简单的iOS应用程序,没有故事板。我在rootViewController
中为UIWindow
设置了AppDelegate.swift
,如下所示:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let tabBarController = TabBarController()
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.rootViewController = tabBarController
window?.makeKeyAndVisible()
return true
}
TabBarController
类实现如下:
class TabBarController: UITabBarController {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// Next line is called after 'viewDidLoad' method
println("init(nibName: bundle:)")
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
println("viewDidLoad")
}
}
当我运行应用程序时,控制台输出如下所示:
viewDidLoad
init(nibName: bundle:)
这意味着逐行super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
在viewDidLoad
方法之后被调用!这只发生在从UITabBarController
继承的类中。如果您使用UIViewController
后代尝试同样的示例,则一切正常,并在执行init方法之后调用viewDidLoad
。
发布于 2015-07-18 11:27:32
您不能保证只有在完成init方法之后才会调用viewDidLoad
。当视图控制器需要加载其视图层次结构时,将调用viewDidLoad
。
在内部,TabBarController
的init方法(通过调用super.init)正在做一些导致视图加载的事情。
这适用于所有视图控制器。例如:如果您创建一个UIViewController
子类,并在init上执行任何带有其view
属性的操作,比如添加一个子视图,甚至只是设置视图的backgroundColor
属性--您将注意到相同的行为。
发布于 2016-04-18 19:24:34
来自:http://www.andrewmonshizadeh.com/2015/02/23/uitabbarcontroller-is-different/
这并不令人惊讶,但显然UITabBarController与大多数视图控制器有不同的行为。整个生命周期可能是它和其他视图控制器之间的“相同”,但是它执行的顺序不是。
也就是说,当您创建UITabBarController的子类并提供您自己的自定义初始化程序时,您将注意到viewDidLoad方法是以一种意外的方式调用的。也就是说,一旦您调用超级init,它就会在初始化期间调用loadView,这将导致调用您的viewDidLoad。这可能不是你所期望的,因为大多数(全部?)其他UIViewController子类在初始化过程中不实例化它们的视图。因此,如果您提供了自定义初始化程序,并希望在加载视图之前执行一些设置,那么一旦加载视图,添加包含的视图控制器,这将破坏您的逻辑。
解决方案是实际上将安装代码从标准的viewDidLoad方法中移出,并转换为一个特殊的安装方法,该方法在自定义初始化程序的末尾调用。在我看来,这是一种“代码味”,苹果不应该让它通过的。不过,这可能是因为UITabBarController需要向UIViewController的视图中添加一个UITabBar,该视图要求视图存在。这就是激发loadView的原因。
发布于 2015-07-18 11:52:27
看来,init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
for a UITabBarController出于某种原因调用了viewDidLoad
。如果您在print("viewDidLoad")
行上设置了一个断点,您将看到调用是作为初始化序列的一部分进行的。
如果将视图控制器更改为子类UIViewController
,您将看到viewDidLoad
不是作为初始化序列的一部分调用,而是作为调用makeKeyAndVisible
的结果。
我不知道为什么苹果会用这种方式对其进行编码,但我怀疑这是在加载内容视图控制器之前给选项卡条控制器设置设置的机会。
无论如何,如果您想要对UITabBarController
进行子类处理,就必须处理这些问题。
https://stackoverflow.com/questions/31489957
复制相似问题