以下函数Closure use of non-escaping parameter 'completion' may allow it to escape出错
func retrieveCannedRecommendedEntities() -> Future<CannedRecommendedEntities, NSError> {
return Future() { completion in
self.retrieve(.onboarding) { response in
switch response {
case .success(let val):
let payload: AnyObject = val.value.json! as AnyObject
let json = JSON(payload)
guard let suggestions = self.parseEntitiesFromJSON(json, atKey: "suggestion") else {
completion(SqorResult.error(self.parsingError))
}
let teams = suggestions.filter {
$0.entityType != .Player
}
let athletes = suggestions.filter {
$0.entityType == .Player
}
completion(SqorResult.success(Box((teams, athletes))))
case .error(let error):
completion(SqorResult.error(error))
}
}
}
}发布于 2017-01-22 11:57:48
闭包据说是在闭包作为参数传递给函数时转义函数,但在函数返回后调用。
如果您使用闭包异步,意味着闭包可能在函数执行之后被调用,您需要添加@escaping。
即使没有错误编译,也可能存在运行时错误,因为可以释放闭包内存。
@escaping 向您保证防止您的关闭.
发布于 2017-01-20 00:52:57
编译器错误意味着函数Future中的参数Future(这是一个闭包)被指定为“非转义”(这是默认的)。这意味着必须在函数completion返回之前执行闭包Future。
但是,实现表明completion可以“转义”函数Future --这意味着completion可以在函数Future返回后执行。
为了修复这个程序员错误,您需要确保在函数completion返回之前执行闭包Future,或者需要将修饰符@escaping添加到参数completion中。
另见逃逸闭锁
请注意,这两种解决方案都可能有影响,因为它们要么需要更改可能在现有库中定义的函数的API (例如,或者它与您的用例不兼容,因为您在另一个(可能是转义)闭包中调用completion,该闭包在self.retrieve中设置为一个参数。
然而,在“未来”的背景下,“完成”的概念清楚地表明,completion应该是“逃避”。因此,将@escaping添加到Future的函数签名中似乎是可行的。
https://stackoverflow.com/questions/41753657
复制相似问题