首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在执行整个init方法之前调用viewDidLoad。

在执行整个init方法之前调用viewDidLoad。
EN

Stack Overflow用户
提问于 2015-07-18 09:58:31
回答 3查看 7.1K关注 0票数 14

编辑:这是Xcode 6.4的完整代码示例

我有一个简单的iOS应用程序,没有故事板。我在rootViewController中为UIWindow设置了AppDelegate.swift,如下所示:

代码语言:javascript
运行
复制
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类实现如下:

代码语言:javascript
运行
复制
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")
    }

}

当我运行应用程序时,控制台输出如下所示:

代码语言:javascript
运行
复制
viewDidLoad
init(nibName: bundle:)

这意味着逐行super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)viewDidLoad方法之后被调用!这只发生在从UITabBarController继承的类中。如果您使用UIViewController后代尝试同样的示例,则一切正常,并在执行init方法之后调用viewDidLoad

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-07-18 11:27:32

您不能保证只有在完成init方法之后才会调用viewDidLoad。当视图控制器需要加载其视图层次结构时,将调用viewDidLoad

在内部,TabBarController的init方法(通过调用super.init)正在做一些导致视图加载的事情。

这适用于所有视图控制器。例如:如果您创建一个UIViewController子类,并在init上执行任何带有其view属性的操作,比如添加一个子视图,甚至只是设置视图的backgroundColor属性--您将注意到相同的行为。

票数 16
EN

Stack Overflow用户

发布于 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的原因。

票数 13
EN

Stack Overflow用户

发布于 2015-07-18 11:52:27

看来,init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) for a UITabBarController出于某种原因调用了viewDidLoad。如果您在print("viewDidLoad")行上设置了一个断点,您将看到调用是作为初始化序列的一部分进行的。

如果将视图控制器更改为子类UIViewController,您将看到viewDidLoad不是作为初始化序列的一部分调用,而是作为调用makeKeyAndVisible的结果。

我不知道为什么苹果会用这种方式对其进行编码,但我怀疑这是在加载内容视图控制器之前给选项卡条控制器设置设置的机会。

无论如何,如果您想要对UITabBarController进行子类处理,就必须处理这些问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31489957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档