> Что такое capture list в closure и как с ним работать (iOS, Swift)

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

Компании: Masterdata

Стек: iOS, Swift

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

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

Capture list в Swift - это список значений, которые closure захватывает из окружающего контекста. Он указывается в квадратных скобках перед параметрами closure и определяет, как именно захватываются переменные: по значению или по ссылке, а также управляет retain cycle. Основное применение - избегание сильных ссылок на объекты внутри closure, особенно в замыканиях, хранящихся в свойствах класса.

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

Closure в Swift могут захватывать переменные и константы из своего окружения. По умолчанию захват происходит по ссылке для reference types и по значению для value types, но с нюансами: переменные захватываются как var, даже если оригинал был let, если closure изменяет их.

Capture list позволяет явно контролировать этот процесс. Синтаксис: [weak self, unowned self, weak delegate = self.delegate] перед списком параметров.

Основные модификаторы:

  • weak - создает слабую ссылку, объект может быть deallocated, доступ через optional
  • unowned - создает неслабую ссылку, но не увеличивает retain count, предполагает, что объект будет жить столько же, сколько closure
  • Без модификатора - сильная ссылка, retain count увеличивается

Также можно захватывать копию значения: [value = someVariable] - это создает константу, равную значению на момент создания closure.

Главная проблема, которую решает capture list - retain cycle. Если closure хранится в свойстве объекта, а внутри closure захватывает этот объект сильно, возникает цикл: объект → closure → объект. Это приводит к утечке памяти.

На практике

В iOS-разработке capture list чаще всего используется в:

  • Замыканиях, передаваемых в UIView.animate, DispatchQueue.async, URLSession - если closure хранится долго
  • В deinit-проверках для отладки утечек
  • В замыканиях, которые сохраняются как свойства (например, callback в сетевом слое)

Для junior-уровня достаточно понимать:

  • Когда использовать weak - почти всегда, если closure может жить дольше, чем объект
  • Когда unowned - когда объект гарантированно жив, пока жив closure (например, в [unowned self] внутри DispatchQueue.main.async в viewDidLoad)

Пример кода

SWIFT
class NetworkManager {
var onComplete: (() -> Void)?
func fetchData() {
// Сильный захват - retain cycle, если closure хранится в свойстве
onComplete = {
self.processData()
}
}
// Правильно:
func fetchDataCorrect() {
onComplete = { [weak self] in
guard let self = self else { return }
self.processData()
}
}
// С захватом значения:
func fetchDataWithValue() {
let currentID = self.id
onComplete = { [id = currentID] in
print("ID: \(id)")
}
}
private func processData() {
// ...
}
}

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

Начните с определения: capture list - это механизм контроля захвата переменных в closure. Затем объясните проблему retain cycle: приведите пример, когда closure хранится в свойстве и захватывает self. Покажите разницу между weak и unowned. Упомяните, что weak всегда optional, а unowned - нет. Если спросят про value types - скажите, что capture list позволяет захватить копию значения на момент создания closure.

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

Интервьюер проверяет:

  • Понимание механизма управления памятью в Swift (ARC)
  • Умение объяснить retain cycle и способы его избегания
  • Знание разницы между weak и unowned
  • Понимание, когда closure захватывает переменную по значению, а когда по ссылке
  • Способность привести практический пример из iOS-разработки

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

  • Использование unowned self без уверенности в времени жизни объекта - это частая причина crash
  • Забывание guard let self = self при использовании weak self
  • Непонимание, что capture list с [weak self] не решает проблему, если внутри closure создается сильная ссылка на другой объект
  • Путаница между захватом переменной и захватом значения: [value = someVar] создает копию, а не ссылку
  • Использование capture list для value types без необходимости - это просто копирование, которое можно сделать и без capture list

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

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