> Зачем в бизнес-логике используются слабые ссылки в Swift? (iOS, Swift)

Уровень: senior · Роль: mobile · Категория: Технические вопросы

Компании: Eltex

Стек: iOS, Swift

> Пример ответа

Короткий ответ

Слабые ссылки в бизнес-логике Swift используются для разрыва циклов сильных ссылок (retain cycles), которые возникают при замыканиях, делегатах или долгоживущих объектах. Они позволяют избежать утечек памяти, когда объект должен существовать только пока на него есть сильная ссылка извне. В бизнес-логике это критично для сервисов, координаторов и хранилищ, которые захватывают другие объекты, но не должны продлевать их жизненный цикл.

Подробное объяснение

В бизнес-логике iOS-приложений слабые ссылки решают три основные задачи:

  1. Разрыв retain cycles в замыканиях - когда сервис хранит замыкание, которое захватывает сам сервис или его зависимость, возникает цикл. Слабый захват ([weak self]) позволяет объекту освободиться, когда внешние владельцы отпускают его.

  2. Делегирование без владения - делегат не должен владеть своим делегатором. Если оба объекта сильные, они никогда не освободятся. Слабая ссылка на делегата - стандартный паттерн.

  3. Кэши и наблюдатели - слабые ссылки позволяют хранить объекты, которые могут быть освобождены в любой момент (например, в NSCache или пуле слабых ссылок), не блокируя их деаллокацию.

В бизнес-логике важно понимать: слабая ссылка - это не "магическое решение", а инструмент управления временем жизни. Она сигнализирует: "этот объект не принадлежит мне, я просто наблюдаю за ним". Если объект нужен всегда - используйте сильную ссылку. Если он может исчезнуть - слабую, с обязательной проверкой на nil.

На практике

В реальном коде слабые ссылки в бизнес-логике встречаются:

  • В координаторах навигации - координатор держит слабую ссылку на текущий экран, чтобы не блокировать его освобождение.
  • В сервисах с подписками - сервис хранит слабые ссылки на подписчиков, чтобы не удерживать их в памяти после закрытия экрана.
  • В репозиториях с кэшем - кэш использует слабые ссылки на объекты, которые могут быть пересозданы.
  • В DI-контейнерах - зависимости, которые должны жить только пока нужны, регистрируются как слабые.

Ключевой момент: в бизнес-логике слабая ссылка всегда сопровождается проверкой guard let, потому что объект может быть освобожден в любой момент. Это добавляет явную обработку отсутствия зависимости.

Пример кода

SWIFT
final class OrderService {
private weak var delegate: OrderServiceDelegate?
private var onStatusChange: ((OrderStatus) -> Void)?
func setDelegate(_ delegate: OrderServiceDelegate) {
self.delegate = delegate
}
func subscribe(onStatusChange: @escaping (OrderStatus) -> Void) {
self.onStatusChange = onStatusChange
}
func process(order: Order) {
// ... бизнес-логика
// Слабая ссылка на делегата - делегат не обязан жить вечно
delegate?.orderDidProcess(order)
// Замыкание захватывает self слабо, чтобы не создавать цикл
onStatusChange?(.completed)
}
deinit {
print("OrderService deallocated")
}
}
// Использование в координаторе
final class OrderCoordinator {
private let service: OrderService
init(service: OrderService) {
self.service = service
service.setDelegate(self)
}
}
extension OrderCoordinator: OrderServiceDelegate {
func orderDidProcess(_ order: Order) {
// обработка
}
}

Как отвечать на собеседовании

Начните с главной цели - предотвращение утечек памяти через retain cycles. Затем приведите конкретный сценарий из бизнес-логики: сервис с делегатом или замыканием. Объясните, почему сильная ссылка здесь опасна: объекты никогда не освободятся, что приведет к росту памяти. Упомяните, что слабая ссылка - это компромисс: вы теряете гарантию существования объекта, но получаете корректное управление памятью. Покажите понимание, когда слабые ссылки не нужны (например, для короткоживущих объектов или когда владение очевидно). Если спросят про unowned - объясните разницу: unowned предполагает, что объект жив, и крашится при обращении к nil, а weak безопасен.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание жизненного цикла объектов в Swift и ARC.
  • Умение выявлять retain cycles в реальном коде.
  • Знание паттернов: делегирование, координаторы, подписки.
  • Способность объяснить trade-off между weak и unowned.
  • Понимание, что слабая ссылка - это не "всегда хорошо", а осознанный выбор.

Типичные ошибки

  • Использование weak везде подряд, без анализа необходимости - это снижает читаемость и производительность.
  • Забывание проверки на nil после слабой ссылки - обращение к освобожденному объекту.
  • Путаница между weak и unowned - unowned опасен, если объект может быть освобожден.
  • Непонимание, что слабая ссылка не гарантирует существование объекта - это не замена сильной ссылке.
  • Использование слабых ссылок для объектов, которые должны жить все время работы приложения (например, синглтоны).

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью