Ответ
Да. Замыкания являются ссылочными типами и могут быть присвоены свойствам класса или структуры.
Ключевой аспект — управление памятью. Если замыкание захватывает self, необходимо предотвратить сильные циклические ссылки (retain cycles).
Пример безопасной реализации:
class MyClass {
var closure: (() -> Void)?
init() {
// Используем weak capture, чтобы избежать retain cycle
closure = { [weak self] in
self?.doSomething()
}
}
private func doSomething() {
print("Action performed")
}
}
Рекомендации:
- Всегда используйте
[weak self]или[unowned self], если замыкание, хранимое как свойство, захватываетself. - Тип свойства должен соответствовать сигнатуре замыкания (например,
(() -> Void)?).
Ответ 18+ 🔞
Ну, слушай, вот смотри, как это бывает. Ты пишешь класс, всё у тебя красиво, замыкание там, логика... А потом — бац! — приложение как ляжет, а ты сидишь и чешешь репу: "Ну что за хуйня?". А это, блядь, retain cycle подкрался, как маньяк в подворотне.
Так вот, да, замыкания — это ссылочные типы, их можно тыкать куда угодно, хоть в свойство класса. Но вся соль, ёпта, в управлении памятью. Если твоё замыкание, хранимое в классе, вдруг возьмёт и схватит self — всё, пиши пропало. Круговая порука получается: класс держит замыкание, замыкание держит класс, и оба они смотрят друг на друга, как два идиота, и ждут, когда же их отпустят. А сборщик мусора машет им ручкой: "Ребята, вы же друг за друга держитесь, я вас не могу!"
Чтобы не было этой ебанины, надо ловить self аккуратно. Слабенько так, без фанатизма.
Смотри, как надо делать, если не хочешь потом волосы на жопе рвать:
class MyClass {
var closure: (() -> Void)?
init() {
// Смотри сюда, самый важный момент, блядь!
// Ловим self, но [weak]'ом, как хитрожопый кот мясо из холодильника.
closure = { [weak self] in
// А тут уже безопасно дергаем метод, но через вопросик.
// Если self уже помер — ну и хуй с ним, просто тихо сдохнем.
self?.doSomething()
}
}
private func doSomething() {
print("Action performed")
}
}
Вот и вся магия, ёбана. Запомни, как "Отче наш":
- Если замыкание живёт в свойстве и тыкается в
self— обязательно вешай[weak self]или, в крайнем случае,[unowned self](но это уже как русская рулетка, один раз проебёшься). - И да, сигнатура свойства должна точно совпадать с тем, что ты в замыкании городишь. Нельзя
(() -> Void)?присвоить(Int) -> String, это ж не пазл, блядь, чтобы тыкать наугад.
Следуй этим простым правилам, и твои объекты будут умирать красиво и вовремя, а не висеть в памяти, как призраки в заброшенном замке.