Ответ
Да, можно. Поскольку замыкания в Swift являются ссылочными типами, их можно хранить в коллекциях, таких как массивы. Для этого необходимо явно указать тип элементов массива как тип замыкания.
Пример:
// Массив замыканий, которые не принимают и не возвращают значения
var completionHandlers: [() -> Void] = []
func addClosure(_ closure: @escaping () -> Void) {
completionHandlers.append(closure)
}
addClosure { print("Выполнено задание 1") }
addClosure { print("Выполнено задание 2") }
// Последовательный вызов всех замыканий
for handler in completionHandlers {
handler()
}
// Вывод:
// Выполнено задание 1
// Выполнено задание 2
Важные аспекты:
- Типизация. Все замыкания в массиве должны иметь идентичную сигнатуру (тип принимаемых и возвращаемых значений).
- Захват переменных (
capture). Замыкания захватывают переменные из окружающего контекста по сильной ссылке (strong reference) по умолчанию. - Циклы сильных ссылок. Если замыкание захватывает
self, аselfхранит этот массив, может возникнуть цикл удержания. Используйте списки захвата[weak self]или[unowned self].class Controller { var handlers: [() -> Void] = [] func setupHandler() { // БЕЗОПАСНО: предотвращаем цикл сильных ссылок handlers.append { [weak self] in self?.doWork() } } func doWork() {} }