Swift Closure Value Capture范围

时间:2016-06-23 14:37:41

标签: ios swift closures swift3 ios10

我有一个使用Swift 3的问题,我试图从我的完成闭包中访问任务变量,但它不可用。如果我尝试访问块内的“任务”,我会收到“错误:使用未解析的标识符'任务'”我做错了什么?

typealias completionHandler = (data: Data?, httpResponse: HTTPURLResponse?, validServer: Bool, serverRealm: String?, serverVersion: String?) -> Void
typealias failureHandler = (data: Data?, response: URLResponse?, error: NSError?) -> Void


func ping(address: String, completionBlock: completionHandler, failureBlock: failureHandler?) -> URLSessionDataTask? {
    guard var addressComponents = URLComponents(string: address) else {
        let error = NSError(domain: "PING", code: 99, userInfo: [NSLocalizedDescriptionKey : "Invalid URL: \(address)"])
        failureBlock?(data: nil, response: nil, error: error)
        return nil
    }
    addressComponents.path = Paths.ping.rawValue
    let request = URLRequest(url: addressComponents.url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: gsTimeout)

    //--------------------------------------------------------------------------------
    //  Ping the server and process the repsonse
    //--------------------------------------------------------------------------------
    var task: URLSessionDataTask!
    task = session.dataTask(with: request) { (data, response, error) in
    print("Task: \(task)")
        if error == nil {
            if let response = response as? HTTPURLResponse {
                let results = self.parseHeader(response)
                print("Results: \(results)")
                if results.isServer == true {
                    completionBlock(data: data, httpResponse: response, validServer: results.isServer, serverRealm: results.realm, serverVersion: results.serverVersion)
                } 
            }
        } else {
            failureBlock?(data: data, response: response, error: error)
        }
    }

    task.taskDescription = Paths.ping.rawValue
    task.resume()
    return task
}

立即更新了工作代码。如果您在块内使用它,则任务可用。谢谢大家

1 个答案:

答案 0 :(得分:1)

您的代码没有任何问题。它编译得很好。

在调试器中暂停时,您无法 aws-erc-logged-in: cmd.run: - name: $(aws ecr get-login --region={{ pillar['aws']['region'] }}) 使用LLDB po的值,因为您在完成块内暂停了。您从未在此代码中捕获task(您没有引用它),因此它不在此范围内。闭包内部只捕获闭包内部实际引用的外部作用域