Язык Swift
Swift — язык с приматом значений и безопасностью на этапе компиляции, и именно отсюда начинается почти любое iOS-собеседование — не с UIKit или SwiftUI, а с языковой модели под ними. Сквозная идея в том, что Swift превращает целые классы ошибок в ошибки компиляции. Optional превращает «этого может не быть» в тип, который компилятор заставляет обработать, — и краш по nil-указателю просто не скомпилируется. Значимая семантика struct означает, что присваивание копирует значение, поэтому две переменные никогда случайно не ссылаются на одно изменяемое состояние. Ограничение дженерика позволяет компилятору доказать наличие метода до релиза. Инженер, усвоивший это, перестаёт бороться с компилятором и начинает перекладывать нагрузку на него.
Эта тема ведёт по языку с азов. Начинаем с повседневных инструментов — optional'ы, let против var, enum с associated values, сопоставление с образцом — затем самое проверяемое различие: значимые против ссылочных типов и copy-on-write, делающий копирование дешёвым. Дальше — замыкания и ловушки захвата, приводящие к утечкам; система протоколов и дженериков, заменяющая наследование классов; обработка ошибок через throws / Result / optional'ы; и, наконец, обёртки свойств и макросы — кодогенерация на этапе компиляции за @State и @Observable.
Карта темы
- Основы Swift — optional'ы и безопасное разворачивание,
letпротивvar, вывод типов, enum с associated values, сопоставление с образцом иguard/if let. - Значимые и ссылочные типы — копирование struct против разделения class, copy-on-write, идентичность против равенства, семантика мутаций и миф «struct всегда дёшево копировать».
- Замыкания и функции — семантика захвата и списки захвата,
[weak self]/[unowned self], escaping против non-escaping, функции высшего порядка и@autoclosure. - Протоколы и дженерики — протокол-ориентированный дизайн, associated type и witness-таблицы, ограничения дженериков,
someпротивanyи реализации по умолчанию. - Обработка ошибок —
throws/try/catch, вариантыtry,Result,rethrows,deferи выбор между optional, throwing иResult. - Обёртки свойств и макросы — во что компилируется обёртка,
wrappedValue/projectedValueи чем макрос Swift вроде@Observableотличается от обёртки.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Force-unwrap ! как способ по умолчанию читать optional | Краш по nil доходит до прода вместо обработки |
Обращаться со struct как с class (и наоборот) | Неверное копирование против разделения; ошибки алиасинга или потерянные мутации |
Считать, что копия struct всегда O(1) | Буфер copy-on-write или много полей делают её O(n) при первой записи |
Сильный захват self в escaping-замыкании | Retain cycle утекает view controller |
| Метод только в extension протокола с ожиданием переопределения | Через any P статическая диспетчеризация зовёт версию из extension |
Тянуться к try! или глушить ошибку | Восстановимый сбой становится крашем |
Значение для собеседований
Языковой раунд — это фильтр: он отделяет тех, кто понимает, почему Swift ведёт себя так, от тех, кто зазубрил синтаксис. Ответ «struct копируется при присваивании, поэтому мутация одного никогда не затронет другой, а copy-on-write держит это дёшево до первой записи» сразу читается как senior. Сильнейшие ответы связывают гарантию с механизмом — optional с проверкой nil на компиляции, [weak self] с ARC и retain cycle, some против any со статической и динамической диспетчеризацией — а не пересказывают определение.