PrepBro
Профессии
PrepBro
Профессия:

Подготовка

  • Вопросы2048
  • Задачи17

Аналитика

  • hh статистика
  • Анализ резюме

Практика

  • Тестовое собеседование
  • Mock-собеседование
  • Менторы

Поддержка / отзывы

Telegram админа
Профессия:

Подготовка

  • Вопросы2048
  • Задачи17

Аналитика

  • hh статистика
  • Анализ резюме

Практика

  • Тестовое собеседование
  • Mock-собеседование
  • Менторы

Поддержка / отзывы

Telegram админа
Все 24 профессии
Android DeveloperData AnalystSystem Analyst1С DeveloperiOS DeveloperBusiness AnalystJava DeveloperData ScientistQA EngineerQA AutomationPHP BackendC/C++ BackendDevOps EngineerIT Project ManagerFrontend DeveloperNode.js BackendUnity DeveloperC# BackendProduct AnalystFlutter DeveloperPython DeveloperIT Product ManagerGo DeveloperData Engineer

© 2026 PrepBro. Все права защищены.

Telegram-бот

Вопросы по iOS Developer

Что такое KeyPath в Swift и как его использовать?
2.0 Middle🔥 30💬 1

Что такое KeyPath в Swift?

KeyPath (Ключевой путь) — это тип в Swift, который предоставляет ссылку на свойство типа, а не на его значение. Это механизм ключ-значение (key-value), который позволяет получать или устанавливать значения свойств косвенно, используя строковые или типобезопасные пути к ним. KeyPath является объектом первого класса (first-class citizen) в Swift, что означает, что его можно передавать как аргумент, возвращать из функций или сохранять в переменных.

Основные виды KeyPath

Swift предлагает несколько видов KeyPath, каждый с разными возможностями:

1. KeyPath<Root, Value>

Базовый тип, предоставляющий только чтение (read-only) значения свойства.

struct Person {
    var name: String
    var age: Int
}

let nameKeyPath: KeyPath<Person, String> = \Person.name
let person = Person(name: "Анна", age: 30)
print(person[keyPath: nameKeyPath]) // Вывод: Анна
Читать полностью ->
Является ли Swift строготипизированным?
1.6 Junior🔥 30💬 2

Является ли Swift строготипизированным языком?

Да, Swift является строготипизированным языком (или языком со строгой типизацией). Это означает, что типы данных переменных, констант и выражений проверяются на этапе компиляции, и неявные преобразования между несовместимыми типами запрещены. Такая система типов — одна из ключевых особенностей Swift, способствующая надежности, безопасности и производительности кода.

Основные аспекты строгой типизации в Swift

1. Обязательное объявление и вывод типов

  • Каждая переменная или константа имеет явный или выведенный компилятором тип.
  • Примеры:
    // Явное указание типа
    var name: String = "Анна"
    let count: Int = 10
    

// Вывод типа (type inference) let message = "Привет, мир!" // Компилятор определяет тип String let number = 42 // Тип Int выводится автоматически ```

Читать полностью ->
Что такое nonescaping closure?
1.3 Junior🔥 30💬 1

Что такое nonescaping closure в Swift

Nonescaping closure (не сбегающее замыкание) — это тип замыкания в Swift, которое гарантированно завершает своё выполнение до того, как функция, принимающая его в качестве параметра, вернёт управление. Такой тип замыкания не может "пережить" область видимости функции, в которой оно используется, и не может быть сохранено для последующего выполнения.

Ключевые характеристики nonescaping closure

По умолчанию все замыкания являются nonescaping начиная с Swift 3. Это важное изменение, которое повышает безопасность и производительность:

// По умолчанию - nonescaping
func processData(completion: (Int) -> Void) {
    let result = 42
    completion(result) // Вызывается ДО возврата из функции
}

// Явное указание не требуется, так как nonescaping по умолчанию
func calculateSum(_ numbers: [Int], handler: (Int) -> Void) {
    let sum = numbers.reduce(0, +)
    handler(sum) // Выполняется синхронно в рамках функции
}
Читать полностью ->
Что такое body?
1.3 Junior🔥 30💬 2

Что такое body в iOS-разработке?

В контексте iOS-разработки и фреймворков SwiftUI/Combine термин body является фундаментальным понятием, имеющим несколько ключевых значений в зависимости от контекста использования. Это не просто переменная или метод — это центральный механизм декларативного описания пользовательского интерфейса и обработки данных.

1. Body в SwiftUI: сердце декларативного UI

В SwiftUI body — это вычисляемое свойство протокола View, которое определяет структуру и содержимое представления. Каждый пользовательский интерфейс в SwiftUI строится путем создания типов, соответствующих протоколу View, и реализации свойства body.

Читать полностью ->
Что такое Swift Linking?
1.3 Junior🔥 30💬 2

Что такое Swift Linking?

Swift Linking — это процесс связывания (линковки) скомпилированных объектных файлов, модулей или библиотек, написанных на Swift, в единый исполняемый файл (приложение, фреймворк или динамическую библиотеку) в экосистеме Apple. Этот процесс является частью общего workflow компиляции Swift-кода и выполняется компоновщиком (linker) — обычно ld для macOS/iOS или новым lld для улучшенной производительности.

Ключевые аспекты Swift Linking

Читать полностью ->
Что такое Memory Graph?
2.0 Middle🔥 30💬 1

Что такое Memory Graph?

Memory Graph (Граф памяти) — это инструмент отладки и визуализации в среде Xcode, который позволяет наглядно исследовать объектную графовую структуру приложения во время его выполнения. Основная цель — обнаружение и анализ проблем с управлением памятью, прежде всего циклических сильных ссылок (retain cycles) и утечек памяти (memory leaks).

Граф памяти отображает отношения между объектами в виде узлов (объекты) и рёбер (ссылки). Это даёт возможность увидеть, какие объекты удерживают друг друга, что часто сложно выявить при обычной отладке. Инструмент стал особенно актуален с распространением Automatic Reference Counting (ARC), где разработчик не управляет памятью вручную, но должен контролировать связи между объектами.

Ключевые возможности Memory Graph

Читать полностью ->
Что делать, если на View больше одного Gesture Recognizer, чтобы избежать их конфликтов?
1.3 Junior🔥 30💬 1

Управление несколькими Gesture Recognizer в iOS

Когда на UIView добавляется несколько Gesture Recognizer, возникают конфликты распознавания, поскольку система не всегда может определить приоритет обработки жестов. Для решения этой проблемы существует несколько стратегий, которые я применяю в зависимости от конкретного сценария.

Основные методы разрешения конфликтов

1. Установка приоритетов через делегирование

Наиболее гибкий способ — использование протокола UIGestureRecognizerDelegate. Ключевые методы:

Читать полностью ->
Сталкивался ли со снижением производительности TableView?
1.0 Junior🔥 30💬 1

Проблемы производительности UITableView и их решения

Да, сталкивался многократно. Производительность UITableView — классическая проблема в iOS-разработке, особенно при работе с большими объемами данных или сложными ячейками. Основные причины падения производительности:

Ключевые узкие места производительности

  1. Неправильное использование cellForRowAt
  2. Отсутствие повторного использования ячеек
  3. Тяжелые операции в основном потоке
  4. Авторазмер ячеек без кэширования
  5. Избыточные перерисовки и layout операции

Основные решения и оптимизации

1. Оптимизация повторного использования ячеек

// ПРАВИЛЬНО: Регистрация и использование reuse identifier
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
Читать полностью ->
Комфортно ли работать в команде?
1.3 Junior🔥 30💬 1

Уровень комфорта при работе в команде

Как опытный iOS-разработчик с более чем 10-летним стажем, я считаю работу в команде не просто комфортной, а необходимым и крайне продуктивным аспектом профессиональной деятельности. Современная разработка мобильных приложений — это слишком сложная и многогранная задача, чтобы с ней можно было справиться в одиночку, особенно в контексте коммерческих проектов с жёсткими сроками и требованиями к качеству.

Почему командная работа является ключевой для iOS-разработчика

  1. Сложность современных iOS-проектов. Сегодняшние приложения часто включают:
    • Сложную архитектуру (VIPER, Clean Architecture, MVVM-C).
    • Модульность (разбиение на фреймворки или SPM-пакеты).
    • Интеграцию множества сервисов (бэкенд, аналитика, push-уведомления, карты).
    • Совместную разработку с Android- и веб-командами. Всё это требует слаженных усилий.
Читать полностью ->
Ко скольким проектам подключался уже в процессе разработки?
1.0 Junior🔥 30💬 2

Опыт подключения к проектам на разных стадиях

За свою карьеру я подключался к десяткам проектов на совершенно разных стадиях разработки — от "зелёного поля" (с нуля) до легаси-систем с многолетней историей, требующих срочного рефакторинга или поддержки. Условно можно выделить несколько ключевых сценариев:

1. Подключение к проекту на ранних стадиях (MVP / начало разработки)

Обычно это проекты, где только сформирована базовая архитектура, но ключевые фичи ещё не реализованы. Основные задачи здесь:

  • Анализ и, возможно, корректировка выбранной архитектуры (часто это MVVM или VIPER).
  • Настройка инфраструктуры: CI/CD (часто GitHub Actions или Bitrise), менеджер зависимостей (CocoaPods или Swift Package Manager), конфигурация проектов.
  • Разработка основных модулей и настройка коммуникации с бэкендом.

Пример: подключение к проекту, где был только набросок UI в Storyboard, но не было реализовано сетевое взаимодействие.

Читать полностью ->
Какую проблему решают weak и unowned ссылки?
2.0 Middle🔥 30💬 1

Проблема сильных ссылочных циклов в Swift

Weak и unowned ссылки решают фундаментальную проблему управления памятью в Swift — циклические или сильные ссылочные циклы (strong reference cycles), которые приводят к утечкам памяти.

Суть проблемы

В Swift используется Automatic Reference Counting (ARC) — система автоматического подсчета ссылок. Каждый раз, когда создается сильная ссылка на объект, его счетчик ссылок увеличивается на 1. Когда ссылка уничтожается — счетчик уменьшается. Когда счетчик достигает нуля — память освобождается.

Проблема возникает, когда два объекта имеют сильные ссылки друг на друга:

class Person {
    let name: String
    var apartment: Apartment?  // Сильная ссылка на Apartment
    
    init(name: String) {
        self.name = name
    }
}

class Apartment {
    let unit: String
    var tenant: Person?  // Сильная ссылка на Person
    
    init(unit: String) {
        self.unit = unit
    }
}
Читать полностью ->
Какие знаешь типы свойств?
1.3 Junior🔥 30💬 1

Типы свойств в Swift

В Swift свойства делятся на несколько категорий, каждая из которых имеет свои особенности и варианты использования.

Основные категории свойств

1. Stored Properties (Хранимые свойства)

  • Сохраняют константные или переменные значения как часть экземпляра
  • Могут быть объявлены в классах и структурах
struct Person {
    var name: String // хранимое свойство-переменная
    let id: Int      // хранимое свойство-константа
}

2. Computed Properties (Вычисляемые свойства)

  • Не хранят значения, а предоставляют геттер и опционально сеттер для получения/установки значений
  • Доступны в классах, структурах и перечислениях
Читать полностью ->
Какие знаешь init в классе?
1.0 Junior🔥 30💬 1

Инициализаторы (Initializers) в Swift

В Swift инициализаторы — это специальные методы, которые подготавливают экземпляр класса, структуры или перечисления к использованию. В контексте классов существует несколько видов инициализаторов, каждый со своей спецификой.

Основные типы инициализаторов

1. Designated Initializers (Назначенные инициализаторы)

Это основные инициализаторы класса. Они полностью инициализируют все свойства, объявленные в классе, и вызывают инициализатор суперкласса (если он есть).

class Person {
    var name: String
    var age: Int
    
    // Назначенный инициализатор
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

2. Convenience Initializers (Вспомогательные инициализаторы)

Это вторичные инициализаторы, которые вызывают назначенный инициализатор того же класса. Они обозначаются ключевым словом convenience.

Читать полностью ->
В чем разница между потоком и главным потоком?
1.0 Junior🔥 30💬 3

В чем разница между потоком и главным потоком?

В iOS разработке, основанной на UIKit и SwiftUI, разница между потоком (thread) и главным потоком (main thread) является фундаментальной для понимания многопоточности, производительности и безопасности приложения.

Определение потоков

Поток (thread) — это наименьшая единица выполнения внутри процесса. Приложение может создавать множество потоков для параллельного выполнения задач, что называется многопоточностью (multithreading). Потоки позволяют разделять работу, например, выполнять сетевые запросы, обработку данных или тяжелые вычисления без блокировки пользовательского интерфейса.

Главный поток (main thread) — это особый, единственный поток, созданный системой при запуске приложения. Он отвечает за всё, что связано с пользовательским интерфейсом (UI):

Читать полностью ->
В чем разница между передачей данных через Closure и Delegate?
1.2 Junior🔥 30💬 2

Разница между Closure и Delegate в Swift

В iOS разработке на Swift обе паттерны — Closure (замыкания) и Delegate (делегирование) — используются для передачи данных и обратной связи, но имеют фундаментальные различия в архитектуре, применении и степени связности компонентов.

Closure (Замыкание)

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

class DataLoader {
    func loadData(completion: @escaping (Result<Data, Error>) -> Void) {
        // Асинхронная операция
        DispatchQueue.global().async {
            let data = Data()
            completion(.success(data))
        }
    }
}
Читать полностью ->
Что такое асинхронность?
1.0 Junior🔥 30💬 3

Асинхронность: основные принципы

Асинхронность — это парадигма программирования, позволяющая выполнять задачи независимо от основного потока выполнения, не блокируя его на время ожидания результата. В отличие от синхронного выполнения, где каждая операция ожидает завершения предыдущей, асинхронный код может инициировать длительную задачу (например, сетевой запрос или чтение файла) и продолжить выполнение других операций, обработав результат позже, когда он станет доступен.

Читать полностью ->
Почему ищешь работу?
1.0 Junior🔥 30💬 1

Почему я ищу новую работу

Как опытный iOS-разработчик с более чем 10 годами в индустрии, я подхожу к смене работы осознанно и стратегически. Мои причины сочетают профессиональные амбиции, стремление к росту и желание работать над значимыми продуктами.

Ключевые мотивы

  1. Профессиональный рост и новые вызовы
    После многих лет успешной работы над коммерческими приложениями я стремлюсь к задачам, которые расширят мои экспертные границы. Меня привлекают:
    • Разработка под новые платформы (visionOS, iPadOS с Stage Manager)
    • Внедрение современных архитектур (TCA, SwiftUI с Combine)
    • Оптимизация производительности в крупных codebase
Читать полностью ->
Что такое ООП?
1.0 Junior🔥 30💬 1

Объектно-ориентированное программирование (ООП)

Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на концепции «объектов», которые содержат данные (в виде полей или атрибутов) и методы (функции) для работы с этими данными. Вместо написания последовательности инструкций, разработчик создаёт модели реальных сущностей, что делает код более модульным, переиспользуемым и легким в поддержке. ООП особенно актуально для разработки под iOS, где фреймворки (UIKit, SwiftUI) построены на его принципах.

Основные принципы ООП

  1. Инкапсуляция Это механизм сокрытия внутренней реализации объекта и предоставления контролируемого доступа к данным. В Swift это достигается через модификаторы доступа (private, fileprivate, internal, public, open). Инкапсуляция защищает целостность состояния объекта.
Читать полностью ->
Как реализуешь словарь?
1.0 Junior🔥 30💬 1

Realizacija Slovarja v Swift

Slovari (Dictionaries) - jedno iz samyh vazhnyh kollekcij v Swift. Eto asociativnyj massiv, gde kazhdjyj element imeeт paru klyuch-znachenie. Pozvolyaet razobrat'sja v vnutrennej realizacii i kak ih ispol'zovat' optimalno.

Bazovoe ispol'zovanie

var slovar: [String: Int] = [:]
slovar["age"] = 30
slovar["count"] = 5

if let age = slovar["age"] {
    print("Age: \(age)")
}

Vnutrennjaja struktura - Hash Table

Swift slovari realizovany na osnove hash-tablicy:

Читать полностью ->
Является ли сегмент данных глобальной памятью?
1.8 Middle🔥 29💬 2

Ответ на вопрос: "Является ли сегмент данных глобальной памятью?"

Этот вопрос затрагивает архитектурные аспекты управления памятью в iOS (и вообще в Unix-подобных системах), а также терминологию, которая может различаться в зависимости от контекста — низкоуровневого (системы, компиляторы) или высокоуровневого (разработка на Swift/Objective-C). Краткий ответ: да, сегмент данных (data segment) можно считать одной из форм глобальной памяти в контексте процесса, но с важными оговорками.

Что такое сегмент данных?

Читать полностью ->
Что такое жизненный цикл View Controller?
1.0 Junior🔥 29💬 1

Жизненный цикл ViewController в iOS

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

Основные фазы жизненного цикла

Жизненный цикл можно разделить на несколько ключевых фаз:

1. Инициализация и загрузка представления

  • init(coder:)/init(nibName:bundle:) — инициализация из Storyboard или программно
  • loadView() — создание или загрузка иерархии представлений (вызывается автоматически, если view равно nil)
  • viewDidLoad() — самый важный метод, вызывается однократно после загрузки view
override func viewDidLoad() {
    super.viewDidLoad()
    // Настройка элементов интерфейса
    // Загрузка начальных данных
    // Настройка жестов и делегатов
}
Читать полностью ->
Сколько работ было?
1.0 Junior🔥 29💬 2

Вопрос о стаже: «Сколько работ было?»

Этот вопрос на собеседовании часто задают не просто для уточнения хронологии, а чтобы оценить стабильность, карьерный рост, глубину опыта и соответствие позиции. Я подхожу к ответу системно, структурируя информацию, чтобы показать не только количество, но и осмысленный путь развития за более чем 10 лет в iOS-разработке.

Моя карьерная траектория

Мой профессиональный путь в iOS-разработке можно разделить на три ключевых этапа, которые отражают эволюцию моих компетенций и рост ответственности:

  1. Формирующий этап (2 позиции, ~4 года): Начал с позиции Junior/Middle iOS Developer в продуктовой компании, где заложил фундамент: Objective-C, UIKit, основы архитектуры (MVC, позже MVP). Затем перешёл в аутсорс年作为 Middle iOS Developer, где столкнулся с разнообразием проектов, Agile-практиками и начал работать с Swift. Этот этап дал широту видения и укрепил технические навыки.
Читать полностью ->
С какими проблемами можно столкнуться при работе с GCD?
2.0 Middle🔥 29💬 1

Проблемы при работе с Grand Central Dispatch (GCD)

При работе с Grand Central Dispatch (GCD) в iOS/macOS разработке можно столкнуться с рядом нетривиальных проблем, которые могут приводить к дедлокам, утечкам памяти, непредсказуемому поведению приложения и снижению производительности. Основные сложности возникают из-за асинхронной природы GCD, особенностей управления очередями и работы с контекстом.

Основные категории проблем

1. Дедлоки (Deadlocks) и взаимные блокировки

Наиболее классическая проблема — deadlock при синхронном выполнении (sync) на текущей очереди. Это вызывает моментальную блокировку потока.

// Классический deadlock в main queue
DispatchQueue.main.sync {
    // Этот код никогда не выполнится
    print("Deadlock!")
}
Читать полностью ->
Надо ли вызывать super при переопределении loadView?
1.3 Junior🔥 29💬 2

Надо ли вызывать super при переопределении loadView?

Нет, при переопределении метода loadView вызывать super.loadView() не нужно и даже не рекомендуется. Это ключевое отличие loadView от большинства других методов жизненного цикла UIViewController, где вызов родительской реализации является стандартной практикой.

Почему не нужно вызывать super.loadView()?

loadView — это метод, в котором контроллер создает свое корневое view программно. Системная реализация (super.loadView()) делает следующее:

  1. Проверяет, существует ли уже view у контроллера (например, было установлено через self.view = ...).
  2. Если view еще не создано, система пытается загрузить его из Storyboard или XIB-файла, если они связаны с контроллером.
  3. Если интерфейс не загружен из nib, система создает пустое UIView и присваивает его свойству self.view.
Читать полностью ->
Сталкивался ли с проблемами связанными с многопоточностью?
1.8 Middle🔥 29💬 2

Встречался с проблемами многопоточности в iOS

Да, многопоточность в iOS — одна из ключевых и сложных областей. В своей практике я регулярно сталкивался с различными проблемами, от классических race conditions до более специфичных для платформы, таких как UI updates from background threads. Эти проблемы требуют глубокого понимания моделей памяти, механизмов синхронизации и особенностей фреймворков GCD (Grand Central Dispatch) и OperationQueue.

Основные категории проблем и их решения

1. Race Conditions и Data Races

Самая распространенная проблема — одновременный доступ к общему ресурсу из нескольких потоков. Это приводит к неопределенному поведению, крахам или некорректным данным.

// Проблема: Race Condition
class UnsafeCounter {
    private var count = 0
    
    func increment() {
        count += 1 // Небезопасно для нескольких потоков
    }
}
Читать полностью ->
Какие знаешь способы скругления view?
1.0 Junior🔥 29💬 1

Методы скругления углов UIView в iOS

В iOS разработке существует несколько основных подходов для скругления углов представлений (UIView), каждый со своими особенностями и сценариями применения.

1. layer.cornerRadius

Наиболее распространённый и простой метод через свойство слоя (CALayer) представления:

view.layer.cornerRadius = 12.0
view.layer.masksToBounds = true // или view.clipsToBounds = true

Ключевые моменты:

  • Изменяет визуальное отображение, но не изменяет фактическую рамку (frame) представления
  • masksToBounds/clipsToBounds обязательны для обрезки содержимого по скруглённым краям
  • Производительность: аппаратно-ускорено начиная с iOS 3.0
  • Ограничение: скругление только всех углов одновременно

2. UIBezierPath с CAShapeLayer

Более гибкий подход для нестандартных форм:

let path = UIBezierPath(
    roundedRect: view.bounds,
    byRoundingCorners: [.topLeft, .topRight],
    cornerRadii: CGSize(width: 20, height: 20)
)
Читать полностью ->
Какие знаешь способы презентации экрана в UIKit?
2.2 Middle🔥 29💬 2

Способы презентации экрана в UIKit

В UIKit существует несколько подходов для навигации между экранами, каждый со своей спецификой и сценариями использования. Рассмотрим основные способы.

1. UINavigationController (Навигационный стек)

Наиболее распространенный способ для иерархической навигации. Экраны организуются в стек, где можно перемещаться вперед и назад.

Ключевые методы:

  • pushViewController(_:animated:) – добавление нового экрана в стек
  • popViewController(animated:) – возврат к предыдущему экрану
// Презентация нового экрана
let detailVC = DetailViewController()
navigationController?.pushViewController(detailVC, animated: true)

// Возврат назад
navigationController?.popViewController(animated: true)

Преимущества:

  • Автоматическая кнопка "Назад"
  • Управление жестами (свайп для возврата)
  • Сохранение состояния стека
Читать полностью ->
Какие знаешь способы выполнения асинхронного кода?
2.2 Middle🔥 29💬 1

Способы выполнения асинхронного кода в iOS-разработке

Асинхронное программирование в iOS — это фундаментальный подход для выполнения задач без блокировки основного потока, что критически важно для обеспечения плавного пользовательского интерфейса. iOS предлагает несколько ключевых технологий для работы с асинхронным кодом, каждая со своими особенностями и областями применения.

Основные технологии

Grand Central Dispatch (GCD) — это низкоуровневый C-API от Apple для управления параллельными операциями через очереди (queues). Он предоставляет гибкость в управлении потоками.

// Выполнение задачи в фоновом потоке
DispatchQueue.global(qos: .background).async {
    let data = fetchDataFromNetwork() // Долгая операция
    DispatchQueue.main.async {
        self.updateUI(with: data) // Возвращаемся в главный поток для UI
    }
}
Читать полностью ->
Какие знаешь методы, связанные с загрузкой View?
1.0 Junior🔥 29💬 1

Методы, связанные с загрузкой View в iOS (UIKit)

В UIKit процесс загрузки и инициализации UIViewController и его корневого view строго определен и включает несколько ключевых методов. Их понимание критично для корректной работы с жизненным циклом контроллера, управлением памятью и отображением интерфейса.

Основные методы жизненного цикла, связанные с загрузкой view

1. loadView()

Это первичный и самый важный метод, отвечающий за создание корневого view контроллера. Система вызывает его, когда контроллеру требуется его view, но оно еще не создано.

Читать полностью ->
Какая лучшая практика работы с главным потоком и sync?
1.8 Middle🔥 29💬 1

Лучшие практики работы с главным потоком и sync в iOS

Основной принцип, который необходимо помнить при работе с главным потоком (Main Thread/UI Thread) и операциями sync (синхронное выполнение), заключается в следующем: никогда не вызывать синхронные операции (DispatchQueue.main.sync) из самого главного потока. Это приводит к неизбежной блокировке (deadlock) и краху приложения.

Почему возникает deadlock при DispatchQueue.main.sync на главном потоке?

Рассмотрим механизм работы sync:

DispatchQueue.main.sync {
    // Выполнить задачу синхронно на главном потоке
    self.updateUI()
}
Читать полностью ->
Для каких типов данных применим ARC?
1.3 Junior🔥 29💬 1

Область применения ARC (Automatic Reference Counting)

ARC (Automatic Reference Counting) — это механизм автоматического подсчета ссылок, встроенный в компилятор Swift и Objective-C (через Clang), который автоматически управляет памятью для экземпляров классов (reference types). ARC отслеживает, сколько "сильных" ссылок существует на каждый экземпляр, и когда счетчик достигает нуля, память немедленно освобождается.

Типы данных, поддерживаемые ARC

Читать полностью ->
Приведи пример использования weak self
2.0 Middle🔥 29💬 1

Пример использования [weak self] в Swift

[weak self] используется для предотвращения циклов сильных ссылок (strong reference cycles) между объектами, особенно внутри замыканий (closures). Когда замыкание захватывает self как слабую ссылку, это не увеличивает счетчик ссылок на объект, что позволяет избежать утечек памяти.

Ключевые понятия

  • Сильная ссылка: Увеличивает счетчик ссылок на объект, сохраняя его в памяти.
  • Слабая ссылка: Не увеличивает счетчик ссылок; становится nil, когда объект освобождается.
  • Цикл сильных ссылок: Два или более объекта удерживают друг друга через сильные ссылки, препятствуя освобождению памяти.

Пример проблемы: Цикл сильных ссылок

Читать полностью ->
Расскажи про опыт работы с UITableView
1.0 Junior🔥 29💬 1

Мой опыт работы с UITableView

За годы разработки под iOS, UITableView стал для меня одним из фундаментальных инструментов. Это не просто компонент для отображения списков, а целая экосистема, требующая глубокого понимания архитектуры, производительности и взаимодействия с данными.

Архитектура и принципы работы

Основная сила UITableView заключается в его механизме повторного использования ячеек (dequeueReusableCell(withIdentifier:for:)). Это позволяет эффективно управлять памятью, даже при отображении тысяч элементов.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
    cell.configure(with: dataSource[indexPath.row])
    return cell
}
Читать полностью ->
Что такое throws?
1.8 Middle🔥 28💬 1

Что такое throws в Swift

throws — это ключевое слово в Swift, которое указывает, что функция, метод или инициализатор может вызвать ошибку (или «выбросить» её) при выполнении. Это ключевой элемент механизма обработки ошибок в Swift, позволяющий функциям сигнализировать о возникновении проблем без использования альтернативных подходов, таких как опциональные возвращаемые значения или глобальные переменные состояния.

Место в системе обработки ошибок Swift

Swift использует пропагацию ошибок — модель, где ошибки явно передаются (пропагируются) от места возникновения до места обработки. Это отличается от исключений в других языках (например, Java или C++) и является более контролируемым и безопасным подходом.

Читать полностью ->
Что такое UITableViewDataSource?
1.0 Junior🔥 28💬 1

Что такое UITableViewDataSource?

UITableViewDataSource — это протокол (protocol) в iOS-разработке, который предоставляет необходимые данные и методы для наполнения и управления содержимым таблицы (UITableView). Он является частью архитектурного шаблона MVC (Model-View-Controller), где DataSource выступает в роли посредника между моделью данных (Model) и представлением таблицы (View).

Основная задача DataSource — ответить на вопросы таблицы: «Сколько в тебе секций?», «Сколько строк в каждой секции?» и «Какую ячейку (cell) показывать для конкретной строки?». Без реализации этого протокола таблица останется пустой, так как у неё не будет информации для отображения контента.

Обязательные и опциональные методы

Протокол требует реализации как минимум двух обязательных методов:

Читать полностью ->
Что такое @ViewBuilder?
1.8 Middle🔥 28💬 1

Что такое @ViewBuilder

@ViewBuilder — это функциональный строитель (function builder), введенный в SwiftUI для декларативного и типобезопасного построения иерархий представлений. Это не просто атрибут, а фундаментальный механизм, позволяющий SwiftUI комбинировать несколько дочерних вью в единую коллекцию, предоставляя чрезвычайно гибкий и читаемый синтаксис для описания пользовательских интерфейсов.

Основная цель и принцип работы

Главная задача @ViewBuilder — преобразовать несколько отдельных выражений, возвращающих объекты, соответствующие протоколу View, в единую непрозрачную коллекцию вью типа some View. Без него каждый блок кода, возвращающий несколько вью, потребовал бы явного указания типа контейнера (например, TupleView, Group или VStack).

Читать полностью ->
С какими проектами не хотел бы работать?
1.0 Junior🔥 28💬 2

Принципы выбора проектов для iOS-разработчика

Как Senior iOS Developer с 10+ лет опыта, я выработал чёткие критерии оценки проектов. Моё нежелание работать с определёнными типами продуктов основано не на капризах, а на профессиональных принципах, которые напрямую влияют на качество работы, личностный рост и конечную пользу для пользователей.

Категории проектов, которых я избегаю

1. Продукты с неэтичной фундаментальной механикой

Азартные игры и казино-приложения — мой абсолютный red flag. Даже если технически задачи интересны (высокие нагрузки, сложная анимация), я не могу участвовать в создании продуктов, которые:

  • Эксплуатируют психологические зависимости
  • Маскируют реальные финансовые риски под "развлечение"
  • Часто используют тёмные паттерны в UI/UX
Читать полностью ->
Расскажи про свои требования к продукту
1.0 Junior🔥 28💬 2

Я бы сформулировал свои ключевые требования к продукту (в данном контексте — к мобильному приложению или платформе, над которой предстоит работать) с точки зрения Senior iOS Developer, уделяя внимание не только техническим аспектам, но и процессам, которые напрямую влияют на качество результата. Вот мои основные приоритеты:

1. Четкое видение и стратегия продукта

Мне важно понимать долгосрочную цель продукта и его место на рынке. Это помогает принимать взвешенные технические решения, которые будут масштабироваться вместе с продуктом. Например, если планируется выход на международный рынок, сразу закладываю поддержку локализации и адаптивных интерфейсов. Без четкой стратегии легко попасть в ловушку краткосрочных решений, которые в будущем приведут к дорогостоящему рефакторингу.

Читать полностью ->
Почему возникает утечка памяти?
1.8 Middle🔥 28💬 1

Причины утечек памяти (Memory Leaks) в iOS-разработке

Утечка памяти возникает, когда объекты продолжают занимать память, хотя они уже не используются приложением и на них отсутствуют сильные ссылки (strong references). В контексте iOS-разработки на Swift/Objective-C это обычно связано с неправильным управлением жизненным циклом объектов и нарушением принципов ARC (Automatic Reference Counting).

Основные механизмы возникновения утечек

1. Strong Reference Cycles (Циклы сильных ссылок)

Наиболее распространённая причина — взаимное удержание объектов через сильные ссылки:

class User {
    var device: Device?
}

class Device {
    var owner: User?
}

func createLeak() {
    let user = User()
    let device = Device()
    
    user.device = device  // Сильная ссылка на Device
    device.owner = user   // Сильная ссылка на User
    // После выхода из функции оба объекта остаются в памяти
    // Они взаимно удерживают друг друга через strong references
}
Читать полностью ->
Какие знаешь способы верстки?
1.8 Middle🔥 28💬 1

Способы верстки в iOS-разработке

В iOS-разработке существует несколько основных подходов к созданию пользовательского интерфейса, каждый из которых имеет свои особенности, преимущества и сценарии применения. Все их можно разделить на три основные категории: кодовая верстка, верстка в Interface Builder (включая Storyboard и XIB), и декларативные методы (SwiftUI). Рассмотрим каждый подробнее.

1. Кодовая верстка (Programmatic UI)

Это подход, при котором весь интерфейс создается исключительно с помощью кода на Swift или Objective-C, без использования визуальных редакторов.

Преимущества:

  • Полный контроль над каждым элементом и его поведением.
  • Упрощенная работа в команде — отсутствуют конфликты при слиянии изменений в XML-файлах Storyboard.
  • Высокая производительность — исключается время на парсинг Storyboard.
  • Гибкость — легко создавать динамические интерфейсы, которые меняются в зависимости от условий.
Читать полностью ->
Какие есть методы в REST API?
1.6 Junior🔥 28💬 1

Методы HTTP в REST API

В RESTful архитектуре методы HTTP (или HTTP-глаголы) являются ключевым механизмом для определения типа операции, которую клиент хочет выполнить над ресурсом, идентифицируемым URI. Эти методы соответствуют CRUD операциям (Create, Read, Update, Delete) и должны использоваться согласно их семантике, определённой в спецификациях RFC 7231 и RFC 5789. Это обеспечивает единообразие, предсказуемость и корректную работу кэширования, безопасности и идемпотентности.

Основные (базовые) методы

Читать полностью ->
Как реализовываешь Data Source TableView?
1.3 Junior🔥 28💬 1

Реализация Data Source для UITableView: от базовых принципов до современных паттернов

Реализация Data Source — фундаментальный аспект работы с UITableView в iOS-разработке. Эволюция подходов отражает общие тенденции в экосистеме Apple: от простых протоколов до реактивных фреймворков. Рассмотрим ключевые методы и современные практики.

Базовый подход: реализация протокола UITableViewDataSource

Стандартный способ — реализация методов протокола UITableViewDataSource непосредственно в контроллере (чаще всего UIViewController). Это включает два обязательных метода:

Читать полностью ->
Как конфигурируются ячейки?
1.3 Junior🔥 28💬 1

Конфигурация ячеек UITableView и UICollectionView

Конфигурация ячейки — это процесс настройки её внешнего вида и поведения для отображения конкретных данных. Современные подходы значительно эволюционировали с появлением iOS 14, где были введены новые API, делающие конфигурацию более декларативной и безопасной.

Основные подходы к конфигурации

1. Классический подход (до iOS 14)

В этом случае конфигурация происходит в методах tableView(_:cellForRowAt:) или collectionView(_:cellForItemAt:):

Читать полностью ->
К какому виду типов данных относится массив?
1.2 Junior🔥 28💬 1

Массив в Swift относится к коллекциям значений (value types), реализованным как структура (struct), а точнее — к изменяемым коллекциям (mutable collections).

Структурный тип данных (Struct)

Массив в Swift — это не класс, а структура, что является одним из фундаментальных отличий от многих других языков (например, Objective-C, где NSArray является неизменяемым классом, а NSMutableArray — изменяемым). Как структура, массив является типом-значением (value type). Это означает:

  • Копирование при присваивании или передаче в функцию: При каждом присваивании массива новой переменной или передаче его в качестве аргумента функции создаётся его копия. Однако, благодаря механизму Copy-on-Write (CoW), физическое копирование происходит только тогда, когда одна из копий подвергается изменению.
var originalArray = [1, 2, 3]
var copiedArray = originalArray // На этом этапе оба массива ссылаются на одни данные (CoW)
Читать полностью ->
Для чего нужна Strong ссылка?
1.0 Junior🔥 28💬 2

Сильное (Strong) связывание в iOS: фундамент управления памятью

Сильная ссылка (Strong reference) — это тип связи по умолчанию между объектом и его владельцем в ARC (Automatic Reference Counting), системе управления памятью Objective-C и Swift. Её основное предназначение — явно указать, что объект-владелец является ответственным за жизненный цикл ссылаемого объекта. Пока существует хотя бы одна сильная ссылка на объект, он остается в памяти. Когда количество сильных ссылок на объект достигает нуля (т.е. все владельцы отпустили его), ARC автоматически освобождает занимаемую им память.

Как это работает в коде

Рассмотрим на классическом примере отношений между объектами.

class Person {
    let name: String
    var apartment: Apartment? // Сильная ссылка на Apartment
    
    init(name: String) {
        self.name = name
        print("\(name) инициализирован")
    }
    
    deinit {
        print("\(name) деинициализирован")
    }
}
Читать полностью ->
Где мы вызываем методы async/await?
1.0 Junior🔥 28💬 1

Где вызываются async/await методы в iOS-разработке

В iOS-разработке с использованием Swift async/await методы (часть Swift Concurrency) вызываются в асинхронных контекстах, где выполнение кода может быть приостановлено без блокировки потока. Вот ключевые места и способы вызова таких методов:

1. Внутри других async-функций

Основное правило — async функции могут вызываться только из других async функций, используя ключевое слово await. Это прямой и наиболее частый способ:

func fetchUserData() async throws -> User {
    let data = try await downloadData(from: someURL) // await внутри async функции
    return try JSONDecoder().decode(User.self, from: data)
}

2. В Task и его вариантах

Для вызова async методов из синхронного контекста (например, из viewDidLoad или кнопочного обработчика) используется Task:

Читать полностью ->
Что отвечает за визуализацию в UIView?
1.0 Junior🔥 28💬 1

Роль Core Animation и Core Graphics в визуализации UIView

В iOS-разработке визуализация UIView — это многоуровневый процесс, где ключевую роль играют два основных фреймворка: Core Animation и Core Graphics. Сам UIView выступает, прежде всего, контейнером для контента, а непосредственная отрисовка и анимация делегируются нижележащему слою CALayer.

Основные компоненты, отвечающие за визуализацию

Читать полностью ->
Что такое замыкание?
1.3 Junior🔥 28💬 1

Что такое замыкание?

Замыкание (англ. closure) — это функция вместе со всеми захваченными внешними переменными из контекста, в котором она была объявлена. Проще говоря, это функция, которая «запоминает» окружение, в котором она была создана, и может обращаться к переменным из этого окружения даже после того, как контекст выполнения завершился.

Ключевые характеристики замыканий:

  1. Захват переменных — функция сохраняет ссылки на внешние переменные.
  2. Доступ после завершения контекста — захваченные переменные остаются доступными, даже если их область видимости уже завершила работу.
  3. Изменение захваченных переменных — замыкание может не только читать, но и изменять захваченные значения (если они объявлены как изменяемые).

В Swift замыкания являются первоклассными объектами: их можно присваивать переменным, передавать в функции как аргументы и возвращать из функций.

Читать полностью ->
Как избежать утечки памяти?
1.6 Junior🔥 28💬 1

Как избежать утечек памяти в iOS-разработке

Утечки памяти — одна из наиболее распространённых проблем, с которыми сталкиваются iOS-разработчики. Они возникают, когда объекты, которые больше не нужны, не освобождаются из памяти из-за сохранённых на них сильных ссылок. В долгосрочной перспективе это может привести к падению производительности и крашу приложения.

Основные причины утечек памяти

  1. Сильные циклические ссылки (Retain Cycles) — когда два или более объекта удерживают друг друга через сильные ссылки, создавая замкнутый цикл. Самый частый сценарий возникает при использовании замыканий (closures) и делегатов (delegates).

  2. Неправильное использование замыканий — захват self внутри замыкания без использования [weak self] или [unowned self].

  3. Утечки в фоновых потоках — незавершённые операции, которые удерживают объекты.

  4. Неосвобождённые наблюдения (Observers) — например, не удалённые NSNotificationCenter observers или KVO.

Читать полностью ->
Какие знаешь принципы ООП?
1.0 Junior🔥 28💬 1

Основные принципы объектно-ориентированного программирования (ООП)

Объектно-ориентированное программирование — это парадигма, основанная на концепции объектов, которые содержат данные и методы для работы с этими данными. В iOS разработке, особенно при работе с Swift и Objective-C, понимание и применение принципов ООП критически важно для создания модульного, масштабируемого и поддерживаемого кода. Основные принципы ООП включают:

1. Инкапсуляция (Encapsulation)

Инкапсуляция — это механизм сокрытия внутренней реализации объекта и предоставления контролируемого интерфейса для взаимодействия с ним. В Swift это достигается через:

  • Использование private, fileprivate, internal, public и open модификаторов доступа.
  • Свойства с геттерами и сеттерами для контроля над изменением данных.
Читать полностью ->