Swift 3:关闭使用非转义参数可能允许它逃脱

use*_*482 11 ios completionhandler swift xcode8

我有以下功能,我有完成处理程序,但我收到此错误:

Closure use of non-escaping parameter may allow it to escape
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

func makeRequestcompletion(completion:(_ response:Data, _ error:NSError)->Void)  {
    let urlString = URL(string: "http://someUrl.com")
    if let url = urlString {
        let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, urlRequestResponse, error) in
            completion(data, error) // <-- here is I'm getting the error
        })
    task.resume()
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 你们中的任何人都知道我为什么会收到这个错误?

我真的很感谢你的帮助

Mar*_*sso 10

看起来你需要明确定义允许闭包转义.

来自Apple Developer docs,

当闭包作为参数传递给函数时,闭包被称为转义函数,但在函数返回后调用.当您声明一个以闭包作为其参数之一的函数时,您可以在参数的类型之前编写@escaping以指示允许闭包转义.

TLDR; @escaping在完成变量后添加关键字:

func makeRequestcompletion(completion: @escaping (_ response:Data, _ error:NSError)->Void)  {
    let urlString = URL(string: "http://someUrl.com")
    if let url = urlString {
        let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, urlRequestResponse, error) in
            completion(data, error) // <-- here is I'm getting the error
        })
        task.resume()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 现在在Swift 3中,您必须显式定义函数何时包含在调用函数(转义)后执行的完成处理程序.Apple说,"函数在启动操作后返回,但是在操作完成之前不会调用闭包 - 闭包需要转义,以后再调用....如果你没有标记这个参数使用@escaping函数,你会得到一个编译时错误." (3认同)