在学习@escaping标记闭包时,发现当删除@escaping关键词,运行下面的代码:
import Foundation
func performAsyncTask(completion: () -> Void) {
// 异步任务
DispatchQueue.global().async { // 报错行
// 模拟耗时操作
sleep(2)
print("异步任务完成")
// 调用闭包
completion()
}
}
performAsyncTask {
print("执行完成后的回调")
}
就会报错:
Escaping closure captures non-escaping parameter 'completion'
报错的原因为,completion闭包在参数声明中未标记为@escaping,而在异步任务中却尝试使用了它。
问题的关键在于,当闭包作为参数传递并且需要在函数体执行完之后才调用(例如在异步任务中),就必须使用@escaping关键词将其标记为“逃逸闭包”,以便函数返回后仍然能够调用它。
解决方案为,在completion后面添加@escaping关键词。
import Foundation
func performAsyncTask(completion: @escaping () -> Void) {
// 异步任务
DispatchQueue.global().async {
// 模拟耗时操作
sleep(2)
print("异步任务完成")
// 调用闭包
completion()
}
}
performAsyncTask {
print("执行完成后的回调")
}