> Что такое сильные и слабые ссылки в iOS? (iOS, Swift)
Уровень: junior · Роль: mobile · Категория: Технические вопросы
Компании: Wildberries, VK, Masterdata
Стек: iOS, Swift
> Пример ответа
Короткий ответ
Сильные ссылки (strong) удерживают объект в памяти, пока ссылка существует, увеличивая счётчик ссылок. Слабые ссылки (weak) не удерживают объект - при обнулении счётчика ссылок объект освобождается, а weak-ссылка автоматически становится nil. В iOS это критично для избежания retain cycles, особенно в замыканиях и делегатах.
Подробное объяснение
В Swift управление памятью основано на Automatic Reference Counting (ARC). Каждый объект класса имеет счётчик ссылок. Сильная ссылка увеличивает этот счётчик на 1, слабая - не влияет на него. Когда счётчик достигает нуля, объект деаллоцируется.
Слабые ссылки объявляются с ключевым словом weak и всегда должны быть опциональными (var weakRef: SomeClass?), потому что в любой момент могут стать nil. Это безопасно: ARC автоматически обнуляет weak-ссылку при освобождении объекта.
Также существует unowned - похоже на weak, но не опционально и не обнуляется. Используется, когда гарантированно известно, что объект будет жить как минимум столько же, сколько и ссылка. Риск: обращение к unowned после освобождения объекта вызывает crash.
Основная проблема, которую решают слабые ссылки - retain cycle. Это ситуация, когда два объекта ссылаются друг на друга сильно, и ни один не может быть освобождён. Классические примеры: delegate между view controller и view, замыкания, захватывающие self.
На практике
В iOS разработке weak-ссылки используются в трёх основных местах:
-
Делегаты - свойство delegate у UITableView, UICollectionView и других UIKit-компонентов объявлено как weak. Это предотвращает цикл, когда view держит контроллер, а контроллер держит view.
-
Замыкания - при захвате self внутри closure нужно использовать
[weak self]или[unowned self], иначе замыкание будет сильно удерживать объект, а объект - замыкание (через свойство). -
IBOutlets - для связей между storyboard и кодом обычно используются weak, потому что view hierarchy уже сильно удерживает элементы.
Важно понимать разницу: weak подходит для большинства случаев, unowned - только когда вы уверены в жизненном цикле объекта. Например, в замыкании, которое выполняется синхронно и гарантированно не переживёт объект.
Пример кода
SWIFT// Retain cycle через замыканиеclass ProfileViewController: UIViewController {var onSave: (() -> Void)?func setupClosure() {// Плохо: сильный захват selfonSave = {self.saveProfile()}// Хорошо: weak захватonSave = { [weak self] inself?.saveProfile()}// Хорошо: unowned, если гарантирован жизненный циклonSave = { [unowned self] inself.saveProfile()}}func saveProfile() { }}// Делегатprotocol DataServiceDelegate: AnyObject {func didUpdateData()}class DataService {weak var delegate: DataServiceDelegate? // weak, чтобы избежать цикла}
Как отвечать на собеседовании
Начните с определения: сильная ссылка удерживает объект, слабая - нет. Затем объясните механизм ARC и счётчик ссылок. Обязательно упомяните retain cycle и приведите пример с замыканием или делегатом. Покажите понимание разницы между weak и unowned. Для уровня junior достаточно уверенно объяснить базовую механику и привести один-два примера из практики.
Что проверяет интервьюер
Интервьюер оценивает понимание базовых принципов управления памятью в Swift. Важно, чтобы вы не просто знали синтаксис [weak self], но и понимали, зачем это нужно. Проверяется способность объяснить, что происходит с объектом при обнулении счётчика ссылок, и умение выявлять потенциальные retain cycles в коде.
Типичные ошибки
- Путаница между weak и unowned: использование unowned без гарантии жизненного цикла объекта.
- Объявление weak-ссылки как non-optional - это синтаксическая ошибка.
- Забывание
[weak self]в замыканиях, особенно в асинхронных операциях. - Непонимание, что weak-ссылка обнуляется автоматически, и попытка обращаться к ней без проверки на nil.
- Утверждение, что weak увеличивает счётчик ссылок - это неверно.
> Похожие задачи по mobile
Какие существуют модификаторы доступа в Swift
Что делает dispatch_sync в GCD?
Какие преимущества дает использование value types в Swift
Что такое многопоточность
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью