swift 3中的@escaping闭包函数

Posted

技术标签:

【中文标题】swift 3中的@escaping闭包函数【英文标题】:@escaping closure function in swift 3 【发布时间】:2017-01-19 23:35:17 【问题描述】:

以下函数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))
      
    
  

【问题讨论】:

我在 swift3 中使用 xcode 8.2 中的函数。它通过“关闭使用非转义参数'完成'可能允许它转义”引发错误。如果您对此有所了解,请帮助我。 提高代码可读性 【参考方案1】:

当闭包作为参数传递给函数时,称为转义函数,但在函数返回后调用。

如果使用异步闭包,表示函数执行后可能会调用闭包,需要加上@escaping

即使你没有编译错误,你也可能有运行时错误,因为闭包内存可以被释放。

@escaping 向您保证不会关闭。

【讨论】:

感谢您的回复。您能帮我吗?如何将@escaping 添加到完成中。 在完成处理程序之前添加@escaping【参考方案2】:

编译器错误意味着函数Future中的参数completion是一个闭包-被指定为“非转义”(这是默认值)。这意味着,闭包completion 必须在函数Future 返回之前执行

但是,实现表明completion 可以“转义”函数Future - 这意味着completion 可以在函数Future 返回之后执行

为了修复这个程序员错误,你需要确保闭包completion会被执行函数Future返回之前,或者你需要添加修饰符@escaping到参数completion

另见Escaping Closures

请注意,这两种解决方案都可能会产生影响,因为它们要么需要更改可能在现有库中定义的函数的 API(例如“Future”),要么与您的用例不兼容,因为您调用 @ 987654335@ 在另一个 - 可能转义 - 闭包中设置为 self.retrieve 中的参数。

但是,“未来”上下文中的“完成”概念清楚地表明,completion 应该是“转义”。因此,将@escaping 添加到Future 的函数签名似乎是可行的方法。

【讨论】:

感谢您的回复。您能帮我吗?如何将@escaping 添加到完成中。 @saranya 请在此处阅读Escaping Closures。 (向下滚动一点)

以上是关于swift 3中的@escaping闭包函数的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发-Swift进阶之闭包,逃逸闭包 & 非逃逸闭包!

Swift @escaping 仅适用于非空函数参数?

Swift:带有@escaping 闭包的选择器返回 EXC_BAD_ACCESS

当完成处理程序显式使用 @escaping 时,Swift 推断完成处理程序闭包是默认的 @nonescaping 而不是 @escaping

Swift3.0 函数闭包与OC Block

Swift3.0-closure的@autoclosure和@escaping