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

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

Компании: Wildberries, Masterdata

Стек: iOS, Swift

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

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

Closure в Swift - это самодостаточный блок функциональности, который можно передавать и использовать в коде, аналогично лямбдам в других языках. Capture list - это синтаксическая конструкция [weak self] или [unowned self], которая определяет, как closure захватывает переменные из окружающего контекста. Она позволяет управлять памятью и избегать retain cycles, особенно при работе с классами и замыканиями, хранящимися в свойствах.

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

Closure захватывает ссылки на переменные и константы из своего лексического окружения. По умолчанию захват происходит по ссылке (для классов) или по значению (для структур и примитивов). Это значит, что closure может изменять захваченные переменные, и эти изменения будут видны вне closure.

Capture list позволяет явно указать, как захватывать каждую переменную. Основные варианты:

  • [weak self] - захват слабой ссылки, которая становится nil, когда объект освобождается. Используется для избежания retain cycle.
  • [unowned self] - захват безусловной (unowned) ссылки, которая предполагает, что объект будет жив на момент вызова closure. Если объект освобождён, произойдёт crash.
  • [self] - явный захват по значению (для value types) или по ссылке (для reference types) без изменений.
  • Можно комбинировать: [weak self, weak delegate].

Когда closure хранится в свойстве объекта, и closure захватывает этот объект сильно, возникает retain cycle: объект держит closure, closure держит объект. Это приводит к утечке памяти. Capture list с weak или unowned разрывает этот цикл.

На практике

На собеседовании уровня junior важно показать понимание:

  • Когда возникает retain cycle (например, closure как свойство класса).
  • Разницу между weak и unowned и когда что использовать.
  • Что capture list применяется только к переменным, перечисленным в квадратных скобках, а не ко всем захваченным значениям.
  • Что для value types (struct, enum) захват по умолчанию - копия, и capture list не обязателен.

Пример кода

SWIFT
class NetworkManager {
var onComplete: (() -> Void)?
func fetchData() {
// Замыкание хранится в свойстве - нужен capture list
onComplete = { [weak self] in
guard let self = self else { return }
self.processData()
}
}
func processData() {
print("Processing")
}
}
// Пример с value type
struct Counter {
var value = 0
mutating func increment() {
// Для struct захват по значению, capture list не нужен
let closure = {
self.value += 1 // Ошибка: нельзя мутировать self в non-escaping closure
}
}
}

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

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

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

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

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

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

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

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

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