viewDidLoad вызывается перед выполнением всего метода init

РЕДАКТИРОВАТЬ: Вот целый пример кода для 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, все в порядке и viewDidLoad вызывается после выполнения метода init.

10 голосов | спросил Deny 18 J000000Saturday15 2015, 12:58:31

3 ответа


0

Вам не обязательно вызывать viewDidLoad только после завершения метода init. viewDidLoad вызывается, когда контроллеру представления необходимо загрузить свою иерархию представления.

Внутренне метод init TabBarController (вызывая super.init) выполняет что-то, что вызывает загрузку представления.

Это относится ко всем контроллерам представления. Например: если вы создаете подкласс UIViewController и делаете что-либо с его view свойство init, например, добавление подпредставления или даже просто установка свойства backgroundColor представления - вы будете обратите внимание на то же поведение.

ответил Artal 18 J000000Saturday15 2015, 14:27:32
0

От: http://www.andrewmonshizadeh.com/2015 /02/23 /UITabBarController-это-другому /

Это не должно вызывать удивления, но, по-видимому, UITabBarController ведет себя иначе, чем большинство контроллеров представления. Жизненный цикл может в целом быть «одинаковым» между ним и другими контроллерами представления, но порядок его выполнения - нет.

То есть, когда вы создаете подкласс UITabBarController и предоставляете свой собственный инициализатор, вы заметите, что метод viewDidLoad вызывается неожиданным образом. То есть, как только вы вызовете [super init] (или другой инициализатор в UITabBarController), он вызовет loadView во время этой инициализации, что затем приведет к вызову вашего viewDidLoad. Вероятно, это не то, что вы ожидаете, потому что большинство (все?) Других подклассов UIViewController не создают свои представления во время процесса инициализации. Таким образом, если вы предоставили пользовательский инициализатор и ожидали выполнить некоторую настройку до загрузки представления, а затем, после того как представление загружено, добавьте контроллеры представленного содержимого, это нарушит вашу логику.

Решение состоит в том, чтобы фактически переместить ваш установочный код из стандартного метода viewDidLoad в специальный метод установки, который вызывается в конце вашего пользовательского инициализатора. Это производит впечатление «запаха кода», который Apple никогда не должна была пропускать. Вероятно, однако, это потому, что UITabBarController должен добавить UITabBar в представление UIViewController, которое требует, чтобы представление существовало. Именно это запускает loadView.

ответил coolbeet 18 PMpMon, 18 Apr 2016 22:24:34 +030024Monday 2016, 22:24:34
0

Похоже, что init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) для UITabBarController вызывает viewDidLoad по какой-то причине. Если вы установите точку останова в своей строке print("viewDidLoad"), вы увидите, что вызов выполняется как часть последовательности инициализации.

Если вы измените контроллер представления на подкласс UIViewController, вы увидите, что viewDidLoad вызывается не как часть последовательности инициализации, а скорее как результат вызова makeKeyAndVisible

Я не знаю, почему Apple так его кодировала, но я подозреваю, что это дает контроллеру панели вкладок возможность настроить вещи до загрузки контроллеров представления контента.

Независимо от того, с чем вам придется столкнуться, если вы хотите создать подкласс UITabBarController

ответил Paulw11 18 J000000Saturday15 2015, 14:52:27

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132