Каковы ключевые этапы запуска iOS-приложения?

Ответ

Запуск iOS-приложения — это последовательный процесс, управляемый системой:

  1. Загрузка бинарника – Система загружает исполняемый файл приложения и связанные динамические библиотеки (dylibs).
  2. Инициализация Runtime – Загружается и настраивается Objective-C/Swift runtime (регистрация классов, категорий, констант).
  3. Точка входа main() – Вызывается стандартная C-функция main, которая запускает UIApplicationMain.
    UIApplicationMain(
        argc,
        argv,
        nil, // principalClassName (обычно nil для стандартного UIApplication)
        NSStringFromClass(AppDelegate.self) // delegateClassName
    )
  4. Создание UIApplication – Система создает единственный экземпляр UIApplication (или его подкласса).
  5. Загрузка интерфейса – Если в Info.plist указан Main storyboard file base name, система загружает его и создает initial view controller.
  6. Жизненный цикл AppDelegate – Вызывается ключевой метод делегата:
    application(_:didFinishLaunchingWithOptions:) -> Bool
  7. Запуск Run Loop – Приложение переходит в активное состояние (applicationDidBecomeActive(_:)), и главный поток начинает обрабатывать события в run loop.

Ответ 18+ 🔞

Давай разберём этот цирк с конями, который iOS вытворяет, когда ты тапаешь по иконке. Представь, ты нажимаешь на красивую картинку, а там внутри начинается такая движуха, что мама не горюй.

Сначала система, как заправский грузчик, хватает твой бинарник и все эти прицепленные к нему библиотеки (dylibs) — тащит всё это добро в память. Прям как на склад завозят.

Дальше — самое интересное. Просыпается Objective-C/Swift runtime, этот самый ёпта, шаманский дух системы. Он начинает бормотать заклинания: регистрирует все твои классы, категории, константы. Без этой магии ни один @IBOutlet бы не ожил, всё бы лежало мёртвым грузом.

А потом — бац! — точка входа. Старая добрая функция main(), как дед на завалинке. Она только и делает, что зовёт главного запевалу — UIApplicationMain. Смотри, как это выглядит в коде, тут всё честно:

UIApplicationMain(
    argc,
    argv,
    nil, // principalClassName (обычно nil для стандартного UIApplication)
    NSStringFromClass(AppDelegate.self) // delegateClassName
)

Система смотрит на этот вызов и такая: «Ага, понятно». И создаёт один-единственный, священный экземпляр UIApplication. Он как царь и бог в твоём приложении, главный дирижёр этой оркестровой ямы.

Потом, если ты в Info.plist не поленился указать главную сториборду, система её загружает. Это как декорации на сцену выкатывают. Создаётся initial view controller — первый актёр, который выйдет на сцену.

И вот наступает звёздный час твоего AppDelegate. Вызывается ключевой метод, ради которого всё и затевалось:

application(_:didFinishLaunchingWithOptions:) -> Bool

Вот тут-то ты и творишь свою чёрную магию: настраиваешь Firebase, ставишь корневые контроллеры, показываешь онбординг. Возвращаешь true — и понеслась.

Финальный акт — запускается главный run loop. Приложение переходит в активное состояние (applicationDidBecomeActive(_:)), и главный поток начинает крутиться как белка в колесе, обрабатывая тапы, свайпы и системные события. Всё, приложение живое, можно работать. А если что-то пошло не так — ну, бывает, ебать его в сраку, отладчик в руки и вперёд.