Вы можете использовать @escaping
и @autoclosure
, чтобы сохранить функцию и ее параметры как замыкание в свойстве class
, а затем вызвать его.
Добавьте этот класс в свой проект:
// Stored Function Class
class SFC {
static var calledFunc: (() -> Void)?
static func call(_ function: @escaping @autoclosure () -> Void) {
// Store the function
calledFunc = function
// Call it
function()
}
static func reCall() {
// Called the stored function
calledFunc?()
}
// Call this when you no longer want SFC to hold onto your function.
// Your class will not deallocate if you passed in `self` to `call()`
// as long as `calledFunc` retains your function. Setting it to `nil`
// frees it.
static func forget() {
calledFunc = nil
}
}
Вот как вы его используете:
Оберните любой вызов функции, который вы хотите повторить, с помощью SFC.call()
. Вызовите SFC.reCall()
, чтобы снова вызвать эту функцию.
Пример:
func add(_ a: Int, _ b: Int) {
print("\(a) + \(b) = \(a + b)")
}
SFC.call(print("hello", "bye"))
SFC.reCall()
SFC.reCall()
SFC.call(add(2, 3))
SFC.reCall()
Выход:
hello bye
hello bye
hello bye
2 + 3 = 5
2 + 3 = 5
Как это работает?
Содержимое вызова call()
автоматически переносится в замыкание (это то, что делает @autoclosure
) и передается как function
. @escaping
означает, что вы будете висеть на этом закрытии после возвращения call()
.
Это замыкание затем присваивается свойству calledFunc
, чтобы его можно было вызвать позже из reCall()
.
Примечание: Если функция, которую вы передаете call()
, является функцией-членом, вам нужно явно указать self
. Например: SFC.call(self.functionThree(foo: fooVar))
. Обязательно вызовите SFC.forget()
, когда пришло время освободить ваш класс, чтобы SFC
не удерживал ваш экземпляр класса.