加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 06:08:43 所属栏目:百科 来源:网络整理
导读:我有一个协议: enum DataFetchResult { case success(data: Data) case failure}protocol DataServiceType { func fetchData(location: String,completion: (DataFetchResult) - (Void)) func cachedData(location: String) - Data?} 使用示例实现: /// An
我有一个协议:
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。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读