Вы можете найти легко, добавив "вычисленный" свойство контроллера вида:
class TestClass: UIViewController {
let a = {()->Int in print("global initialization"); return 10 }()
}
и добавление
print("didFinishLaunching")
в делегат didFinishLaunchingWithOptions
метода приложения.
заказ вы получаете
global initialization
didFinishLaunching
что означает глобальные инициализаторы запускаются перед началом жизненного цикла приложения.
Теперь, чтобы пойти еще дальше, вы можете добавить main.swift
файл со следующим содержимым
print("Before UIApplicationMain")
UIApplicationMain(CommandLine.argc, unsafeBitCast(CommandLine.unsafeArgv, to: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.self), nil, NSStringFromClass(AppDelegate.self))
и удалить (или комментарий) в @UIApplicationMain
украшение из вашего класса AppDelegate. Это даст указание компилятору использовать код в main.swift
для инициализации приложения вместо стандартного поведения, предоставляемого декоратором в процессе обсуждения (хотя мы предоставляем практически идентичную реализацию).
Что вы получите в этом 2-го подхода является
Before UIApplicationMain
global initialization
didFinishLaunching
, что означает, что код свойства экземпляра выполняется, когда раскадровка загружена.
Теперь, для более глубокого понимания, давайте попробуем выяснить различия между статическими переменными экземпляра. Для этого мы добавим тестовый класс:
class PropertyInitializationTest {
static let staticProp = {()->String in print("static initialization of InitializationTest"); return "" }()
let instanceProp = {()->String in print("instance initialization of InitializationTest"); return "" }()
init() {
print("In initializer")
}
}
и обновление AppDelegate в сделал закончить запуск:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print("didFinishLaunching")
print("before instantiating InitializationTest")
_ = PropertyInitializationTest()
print("after instantiating InitializationTest")
// Override point for customization after application launch.
return true
}
Выход мы получаем:
Before UIApplicationMain
global initialization
didFinishLaunching
before instantiating InitializationTest
instance initialization of InitializationTest
In initializer
after instantiating InitializationTest
, что подтверждает тот факт, эти свойства экземпляра устанавливаются при создании экземпляра класса и перед запуском любого кода инициализации.
Но подождите! Как насчет статического свойства? Нет никаких следов, чтобы указать, что он был инициализирован вообще. Похоже, что статические свойства по определению являются ленивыми и инициализируются только при первом доступе.
Обновление приложения завершило запуск кода, подтверждающего это.
print("didFinishLaunching")
print("before instantiating InitializationTest")
_ = PropertyInitializationTest()
print("after instantiating InitializationTest")
_ = PropertyInitializationTest.staticProp
print("after instantiating InitializationTest")
дает следующий результат:
Before UIApplicationMain
global initialization
didFinishLaunching
before instantiating InitializationTest
instance initialization of InitializationTest
In initializer
after instantiating InitializationTest
static initialization of InitializationTest
after instantiating InitializationTest
Вывод:
- свойства экземпляра получают значения времени компиляции (если он установлен) перед прогонов инициализаторе класса, таким образом, перед любым кодом из этого класса выполняется
- Статические свойства получают свои значения только при первом доступе, они ленивы по своей природе
Отличный ответ !!! Итак, это отвечает на мой вопрос. Другая половина. Было ли время, когда глобальная инициализация будет запущена без viewDidLoad или viewDidLoad без глобальной инициализации класса, в котором они находятся? Это предполагает, что он не падает в середине глобальной инициализации. – Sethmr
@Sethmr Я обновил свой ответ с большим количеством результатов. Вывод состоит в том, что код 'viewDidLoad' будет всегда запускаться после глобальной инициализации, так как это часть настройки, выполняемой при создании экземпляра класса – Cristik
. Спасибо за ваше время. Я могу копаться в таких вещах, но, услышав это от кого-то с более глубоким пониманием, он становится намного легче расти и видит лучший способ понять эти вещи в будущем. – Sethmr