Ответ
Наиболее сложными были асинхронное программирование и управление памятью, требующие глубокого понимания для создания отзывчивых и стабильных приложений.
-
Grand Central Dispatch (GCD) и Concurrency:
- Понимание различий между очередями (
DispatchQueue.mainvs.global). - Избегание взаимных блокировок (deadlocks), особенно при использовании
sync.// Классический deadlock: синхронный вызов на текущей очереди DispatchQueue.main.sync { // Этот код никогда не выполнится, так как блокирует main queue } - Правильная обработка состояний гонки (race conditions) при доступе к общим ресурсам из нескольких потоков.
- Понимание различий между очередями (
-
Управление памятью и циклы сильных ссылок (Retain Cycles):
- Выявление и устранение циклов в замыканиях и между объектами с использованием
[weak self],[unowned self]. - Понимание различий между
weakиunownedссылками.
- Выявление и устранение циклов в замыканиях и между объектами с использованием
-
Новая модель concurrency (async/await):
- Освоение нового синтаксиса и его интеграция с существующим кодом на GCD.
- Понимание
Task,actorи потокобезопасности.
Сложность заключалась в том, что ошибки в этих областях часто проявляются не сразу, а при определенных, иногда редких, условиях, что усложняет отладку.