@scaping关闭函数在swift 3中

时间:2017-01-19 23:35:17

标签: swift swift3 escaping structure completionhandler

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

2 个答案:

答案 0 :(得分:1)

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

如果用于闭包异步,意味着可以在函数执行后调用闭包,则需要添加@escaping

即使您没有错误编译,也可能会出现运行时错误,因为可以释放关闭内存。

@escaping确保您阻止关闭。

答案 1 :(得分:0)

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

然而,实施表明Future可能&#34;逃避&#34;函数completion - 这意味着,函数Future返回后可以执行<{1}}。

为了解决这个程序员错误,你需要确保在函数completion返回之前将>执行闭包Future,或者你需要添加修饰符{ {1}}参数completion

另见Escaping Closures

请注意,两种解决方案都可能有影响,因为它们要么需要更改现有库中可能定义的函数的API(例如&#34; Future&#34;),要么与您的用例不兼容,因为你在另一个中调用Future - 可能是转义 - 在@escaping中设置为参数的闭包。

然而,这个概念&#34;完成&#34;在&#34;未来&#34;的背景​​下明确规定,completion应该&#34;逃避&#34;。因此,将completion添加到self.retrieve的函数签名似乎即可。