如何解决非转义参数的闭包使用可能允许它转义
这是由于函数类型参数的默认行为发生了变化。在 Swift 3 之前(特别是 Xcode 8 beta 6 附带的构建),它们将默认为转义 -
你必须标记它们@noescape
以防止它们被存储或捕获,这保证它们不会超过函数调用的持续时间。
但是,Now@noescape
是函数类型参数的默认值。如果您想存储或捕获此类功能,您现在需要标记它们@escaping
:
protocol DataServiceType {
func fetchData(location: String, completion: **@escaping** (DataFetchResult) -> Void)
func cachedData(location: String) -> Data?
}
func fetchData(location: String, completion: **@escaping** (DataFetchResult) -> Void) {
// ...
}
有关此更改的更多信息,请参阅Swift Evolution 提案。
解决方法
我有一个协议:
enum DataFetchResult {
case success(data: Data)
case failure
}
protocol DataServiceType {
func fetchData(location: String,completion: (DataFetchResult) -> (Void))
func cachedData(location: String) -> Data?
}
通过示例实现:
/// An implementation of DataServiceType protocol returning predefined results using arbitrary queue for asynchronyous mechanisms.
/// Dedicated to be used in various tests (Unit Tests).
class DataMockService: DataServiceType {
var result : DataFetchResult
var async : Bool = true
var queue : DispatchQueue = DispatchQueue.global(qos: .background)
var cachedData : Data? = nil
init(result : DataFetchResult) {
self.result = result
}
func cachedData(location: String) -> Data? {
switch self.result {
case .success(let data):
return data
default:
return nil
}
}
func fetchData(location: String,completion: (DataFetchResult) -> (Void)) {
// Returning result on arbitrary queue should be tested,// so we can check if client can work with any (even worse) implementation:
if async == true {
queue.async { [weak self ] in
guard let weakSelf = self else { return }
// This line produces compiler error:
// "Closure use of non-escaping parameter 'completion' may allow it to escape"
completion(weakSelf.result)
}
} else {
completion(self.result)
}
}
}
上面的代码在 Swift3 (Xcode8-beta5) 中编译并运行,但不再适用于 beta 6。你能指出我的根本原因吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。