Что вы знаете о capture list в Swift?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Capture list в Swift — это механизм, позволяющий явно указать, как замыкание захватывает одну или несколько переменных из окружающей области видимости. Он используется для разрешения проблем с retain cycles, особенно при захвате self.
Существует три типа захвата: weak, unowned и unowned(unsafe).
-
weak: Захватывает переменную как опционал (Optional). Если объект, на который ссылается переменная, будет освобожден, переменная внутри замыкания станетnil. Используется для предотвращения retain cycles, когда одна ссылка может бытьnilв течение жизненного цикла.// Пример с weak class ViewController { var dataTask: URLSessionDataTask? func loadData() { let url = URL(string: "...")! dataTask = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in // self здесь опционал weakSelf guard let self = self else { return } // Распаковка weakSelf self.processData(data: data) } dataTask?.resume() } func processData(data: Data?) { // Обработка данных } } -
unowned: Захватывает переменную как неопознанную ссылку. Предполагается, что объект, на который ссылается переменная, имеет тот же или более длительный жизненный цикл, чем замыкание. Если объект освобождается до выполнения замыкания, попытка доступа к нему вызовет ошибку времени выполнения. Используется, когда одна ссылка гарантированно не nil в течение жизненного цикла.// Пример с unowned class Person { let name: String lazy var greeting: () -> String = { [unowned self] in return "Hello, I'm \(self.name)." } init(name: String) { self.name = name } deinit { print("\(name) is being deinitialized") } } var john: Person? = Person(name: "John") print(john!.greeting()) john = nil // john.greeting() больше не должен быть вызван после этого -
unowned(unsafe): Подобноunowned, но не выполняет проверки времени выполнения. Использование не рекомендуется, если нет специфической необходимости в оптимизации и полной уверенности в жизненном цикле объекта.
Синтаксис capture list: [capture list]. Список помещается сразу после открывающей фигурной скобки замыкания.
// Общий синтаксис
{ [capturingValue1, capturingValue2] (parameters) -> returnType in
// body of closure
}
Выбор между weak и unowned зависит от гарантированного жизненного цикла объектов. Если замыкание и захватываемый объект могут иметь разный жизненный цикл и объект может стать nil, используется weak. Если замыкаемый объект гарантированно существует, пока выполняется замыкание, используется unowned.