Class 带有@escaping 参数的初始化器

Class Initializer with @escaping parameter

我正在设置一个 class 可以理想地存储异步方法供以后使用。我想在 class 初始化器中传递一个函数,但我 运行 遇到了一个奇怪的编译器问题。

Cannot convert value of type '(@escaping (Int) -> Void) -> ()' to expected argument type '((Int) -> Void) -> Void'

如果该方法不是 escaping/sync,则可以正常工作。编译器还建议强制转换参数 as! (((Int) -> Void) -> Void)。试了一下,但它崩溃了。

这是我在操场上玩过的一个例子:

class NumberTwo {
    let numberTwoMethod: ((Int) -> Void) -> Void

    init(numberTwoMethod: @escaping ((Int) -> Void) -> Void) {
        self.numberTwoMethod = numberTwoMethod
    }

    func callNumberTwoMethod() {
        numberTwoMethod { myNum in
            print(myNum)
        }
    }
}

func getNumberTwoMethod(completion: @escaping (Int) -> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        completion(2)
    }
}

func getNumberTwoMethodSync(completion: (Int) -> Void) {
    completion(2)
}

NumberTwo(numberTwoMethod: getNumberTwoMethod) // error: cannot convert value of type '(@escaping (Int) -> Void) -> ()' to expected argument type '((Int) -> Void) -> Void'
NumberTwo(numberTwoMethod: getNumberTwoMethodSync) // Works

关于这里发生的事情的任何建议或将异步函数作为变量存储在 class 中的替代方法?

您缺少 @escaping 的内闭合:

class NumberTwo {
    let numberTwoMethod: (@escaping (Int) -> Void) -> Void

    init(numberTwoMethod: @escaping (@escaping (Int) -> Void) -> Void) {
        self.numberTwoMethod = numberTwoMethod
    }

    func callNumberTwoMethod() {
        numberTwoMethod { myNum in
            print(myNum)
        }
    }
}

或略微简化:

class NumberTwo {
    typealias CompletionHandler = (Int) -> Void
    let numberTwoMethod: (@escaping CompletionHandler) -> Void

    init(numberTwoMethod: @escaping (@escaping CompletionHandler) -> Void) {
        self.numberTwoMethod = numberTwoMethod
    }

    func callNumberTwoMethod() {
        numberTwoMethod { myNum in
            print(myNum)
        }
    }
}

另请注意,这可能会造成内存泄漏,因为任何地方都没有 weak