Главным образом, на том потоке, откуда было вызвано создание экземпляра. Явного ограничения на выполнение init методов на определенном потоке нет.
Однако, следует учитывать особенности:
Main Actor: Если класс или структура помечены как @MainActor, их инициализация по умолчанию будет выполнена в главном потоке, даже если вызов создания экземпляра произошел из другого потока. Это связано с Actor Isolation.
swift
Использование асинхронных примитивов: Async/await и другие инструменты могут влиять на контекст выполнения, но сам метод init остается синхронным. Если внутри init вызывается асинхронная функция, то асинхронная часть будет выполняться в соответствующем контексте (например, на пуле потоков по умолчанию для await), но код до await и после него в init будет выполнен на потоке, где начался init.
** UIKit/AppKit:** Некоторые компоненты UI должны использоваться только в главном потоке. Инициализация таких компонентов (например, UIView) должна происходить в главном потоке, иначе могут возникнуть ошибки или некорректное поведение.
В большинстве случаев, если нет явных ограничений (как @MainActor) или взаимодействия с UI, init просто выполняется на потоке вызова. При необходимости выполнять асинхронную работу или тяжелые вычисления во время инициализации, лучше вынести эту логику за пределы init и выполнить ее асинхронно после создания объекта.