Ответ
Capture list (список захвата) явно определяет, как замыкание захватывает переменные из окружающего контекста. Без него захват происходит по сильной ссылке (strong) по умолчанию, что может привести к retain cycle (циклу сильных ссылок) и утечке памяти.
Проблема (retain cycle):
class ViewController {
var onAction: (() -> Void)?
func setup() {
// Захват self по сильной ссылке -> ЦИКЛ!
onAction = {
self.doSomething() // self удерживает onAction, onAction удерживает self
}
}
}
Решение с capture list:
func setup() {
// [weak self] делает ссылку слабой (weak)
onAction = { [weak self] in
self?.doSomething() // self стал Optional
}
// [unowned self] делает ссылку бесхозной (unowned) – используйте осторожно!
onAction = { [unowned self] in
self.doSomething() // Краш, если self будет освобожден
}
}
Ключевые правила:
- Используйте
[weak]для захвата опциональных ссылок, которые могут статьnil. - Используйте
[unowned]только если захваченный объект гарантированно переживет замыкание. - Также можно захватывать и копировать значения:
[x, y]или[someValue = self.value].
Ответ 18+ 🔞
А, ну вот, опять про эти ваши списки захвата, блядь! Смотри, сейчас объясню, как есть, без соплей.
Значит, смотри. Замыкание — оно как хитрая жопа, которая всё вокруг цепляет и держит. По умолчанию оно хватает всё сильной хваткой, как удав, блядь. И если ты внутри замыкания на self сослался, то всё, пиши пропало — получил цикл сильных ссылок, ёпта.
Вот смотри, классика жанра, пиздец как весело:
class ViewController {
var onAction: (() -> Void)?
func setup() {
// Сейчас будет мясо, блядь!
onAction = {
self.doSomething() // Ёбушки-воробушки! Смотри что делает!
}
}
}
Что тут происходит, а? self держит свойство onAction. А onAction — это замыкание, которое внутри держит self. И они обнимаются, блядь, до скончания времён, как два пидараса шерстяных. Никто никого не отпускает. Память течёт, приложение в пизду. Удивление пиздец!
И вот тут на сцену выходит наш спаситель — capture list, блядь! Это такой чек-лист, где ты указываешь, КАК именно хватать переменные. Не "всех скопом в охапку", а поимённо, с указанием статуса.
func setup() {
// Правильный подход, как у взрослых, блядь!
// [weak self] — делаем ссылку слабой, нежной такой.
onAction = { [weak self] in
self?.doSomething() // И вот он, красавец, стал Optional! Теперь если self умрёт — тут просто будет nil, а не цирк с конями.
}
// А есть ещё вариант для смелых, блядь! [unowned self]
onAction = { [unowned self] in
self.doSomething() // Это как сказать: "Я уверен, что self переживёт это замыкание нахуй!" Но если ошибёшься — краш, пизда тебе в сраку, а не приложение.
}
}
Так, Колян, запоминай правила, чтобы не обосраться:
[weak]— твой главный друг. Используй, когда не уверен, кто кого переживёт. Объект может статьnil, и это норма, блядь. Замыкание просто не выполнится, и все живы.[unowned]— это как ходить по охуенно тонкому льду. Бери только если на 146% уверен, что объект будет жить дольше замыкания. Ошибся — получишь краш, и будешь потом как Герасим: "Мууу... блядь..."- Можно не только ссылки ловить, но и значения копировать, блядь!
[x, y]или вот так:[someValue = self.value]— скопирует значение на момент создания замыкания, и потом похуй, что сself.valueбудет.
Короче, суть в чём: без capture list — это дичь и мракобесие, ведущее к утечкам. С ним — контролируемый захват, порядок и чистота, блядь. Не будь мудаком, используй списки захвата. В рот меня чих-пых, вот и весь сказ!