Ответ
Да, можно. В Swift замыкания (closures) являются first-class типами, что позволяет присваивать их переменным, передавать как аргументы и хранить в коллекциях, включая массивы.
Базовый пример:
// Массив замыканий, не принимающих и не возвращающих значений
var handlers: [() -> Void] = []
let handler1 = { print("Task 1 completed") }
let handler2 = { print("Task 2 completed") }
handlers.append(handler1)
handlers.append(handler2)
// Выполнить все замыкания
handlers.forEach { $0() }
// Вывод:
// Task 1 completed
// Task 2 completed
Практическое применение:
- Цепочки обратных вызовов (callback chains)
- Массивы обработчиков событий (например, кнопка с несколькими действиями)
- Отложенное выполнение задач
Критически важные нюансы:
- Явное указание типа: Компилятору часто требуется явная аннотация типа массива.
-
Циклы сильных ссылок: Если замыкание захватывает
self, это создаёт сильную ссылку.// ❌ Риск утечки памяти closures.append { self.doSomething() } // ✅ Безопасный захват closures.append { [weak self] in self?.doSomething() } - Изменяемость: Если массив объявлен как
let, вы не сможете добавлять или удалять замыкания.
Ответ 18+ 🔞
А, ну ты про это! Да, конечно можно, чё за вопросы. В Swift замыкания — это как бы граждане первого сорта, их можно по переменным раскидать, в аргументы пихать и, само собой, в массивы складывать. Всё честно.
Смотри, элементарный пример:
// Массив замыканий, которые нихуя не принимают и нихуя не возвращают
var handlers: [() -> Void] = []
let handler1 = { print("Task 1 completed") }
let handler2 = { print("Task 2 completed") }
handlers.append(handler1)
handlers.append(handler2)
// Запускаем всю эту карусель
handlers.forEach { $0() }
// На экране:
// Task 1 completed
// Task 2 completed
А где это, блядь, пригождается?
- Цепочки колбэков — когда одно за другим должно выполниться.
- Куча обработчиков на одно событие — типа нажал кнопку, а там целый взвод действий.
- Отложенные задачи — сложил в кучку, а потом разом запустил.
Но вот тут, сука, внимание, важные моменты, а то накосячишь:
- Тип указывай явно. Компилятор иногда тупит, как мартышлюшка, так что лучше ему помочь:
[() -> Void]. -
Циклы сильных ссылок — это пиздец. Если замыкание хватает
self, то держись.// ❌ Так делать — гарантированно получить утечку памяти, ебать мои старые костыли. closures.append { self.doSomething() } // ✅ А вот так — правильно, по-взрослому. closures.append { [weak self] in self?.doSomething() } - Изменяемость. Объявил массив как
let— и всё, приехали. Ни добавить, ни удалить. Терпения ноль ебать, но правила есть правила.