我正在设置一个类,该类可以理想地存储异步方法供以后使用。我想在类初始值设定项中传递一个函数,但是我遇到了一个奇怪的编译器问题。
Cannot convert value of type '(@escaping (Int) -> Void) -> ()' to expected argument type '((Int) -> Void) -> Void'
如果该方法没有转义/同步,则可以正常工作。编译器还建议强制转换参数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
关于这里发生的事情或将异步函数作为变量存储在类中的其他方式的任何建议吗?
答案 0 :(得分:2)
您在内部闭包中缺少@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
。