闭包 – 使用非转义参数可以允许它逃逸

闭包 – 使用非转义参数可以允许它逃逸,第1张

概述我有一个协议: enum DataFetchResult { case success(data: Data) case failure}protocol DataServiceType { func fetchData(location: String, completion: (DataFetchResult) -> (Void)) func cached 我有一个协议:
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了。你能指点我的根本原因吗?

这是由于函数参数的默认行为的改变。在Swift 3(特别是Xcode 8 beta 6附带的版本)之前,他们默认使用转义 – 你必须将它们标记为@noescape,以防止它们被存储或捕获,因此保证它们不会后调用函数退出。

然而,现在@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 proposal。

总结

以上是内存溢出为你收集整理的闭包 – 使用非转义参数可以允许它逃逸全部内容,希望文章能够帮你解决闭包 – 使用非转义参数可以允许它逃逸所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1059614.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存