Сохраните функцию Swift и ее значения параметров и вызовите ее позже - PullRequest
0 голосов
/ 09 января 2019

В моем приложении несколько функций, каждая из которых имеет разное количество параметров

func functionOne(foo: Foo, bar: Bar)

func functionTwo(foo: Foo, bar: Bar, baz: Baz, quux: Quux)

func functionThree(foo: Foo)

Значения параметров могут варьироваться.

Мое требование - нажать кнопку, которая будет работать независимо от того, какая из перечисленных функций была запущена последней, включая значения параметров.

Сохранение всего объекта (функции и параметров) в переменной не сработало.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Вы можете использовать @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 не удерживал ваш экземпляр класса.

0 голосов
/ 09 января 2019

Функция и ее параметры хранятся в замыкании. Например:

func f(x: Int) {}
func g(x: Int, y: Int) {}

var saved: () -> Void = { f(1) }

saved() // this executes f(1)

saved = { g(2, 3) }

saved() // now this executes g(2, 3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...