Ответ
Да, замыкания в Swift являются типами первого класса, поэтому их можно хранить в массивах, словарях и других коллекциях.
Базовый пример:
// Массив замыканий без параметров, возвращающих Void
var tasks: [() -> Void] = []
tasks.append { print("Task 1") }
tasks.append { print("Task 2") }
// Выполнение всех замыканий в массиве
for task in tasks {
task() // Выведет "Task 1", затем "Task 2"
}
Пример с параметрами и возвращаемым значением:
// Массив замыканий, преобразующих Int в String
let transformers: [(Int) -> String] = [
{ "Number: ($0)" },
{ String(repeating: "*($0)", count: 3) },
{ _ in "Constant" }
]
let results = transformers.map { $0(5) }
// results = ["Number: 5", "*5*5*5", "Constant"]
Критически важные аспекты:
- Единая сигнатура: Все замыкания в массиве должны иметь идентичную сигнатуру (типы параметров и возвращаемого значения).
-
Циклы сильных ссылок: Если замыкание захватывает
selfили другие объекты, это может создать retain cycle.class Controller { var closures: [() -> Void] = [] var value = 10 func addClosure() { // ВНИМАНИЕ: Создается сильная ссылка на `self` closures.append { print(self.value) } // Решение: использовать capture list [weak self] closures.append { [weak self] in print(self?.value ?? 0) } } } - Типизация: Для сложных сигнатур используйте
typealiasдля читаемости.typealias CompletionHandler = (Result<Data, Error>) -> Void var completions: [CompletionHandler] = []