存储一个Swift函数及其参数值,并在以后调用

时间:2019-01-09 20:23:43

标签: swift

我的应用程序中有多个功能,每个功能都有不同数量的参数

func functionOne(foo: Foo, bar: Bar)

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

func functionThree(foo: Foo)

参数值可以变化。

我的要求是按下一个按钮,该按钮将运行以上最近运行的功能,包括其参数值。

将整个内容(函数和参数)存储在变量中无效。

2 个答案:

答案 0 :(得分:3)

一个函数及其参数存储在一个闭包中。例如:

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)

答案 1 :(得分:1)

您可以使用@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不会保留在您的类实例上。