swift - 从服务器检索数据时,闭包到底做了什么?

标签 swift closures nsurl

我观看了一个关于闭包的视频,有人通过这种方式演示了闭包的基础知识:

func outer(howMuch: Int) -> () -> Int {
    var total = 0

    inner() {
        howMuch += total
        return total
    }
return inner
}

他接着说,当你这样做时:

let incrementBy10 = outer(10)

他说incrementBy10引用了闭包内的inner()函数。

然后他继续介绍一个检索数据的实际示例:

let url = "*url here*"
let nsURL = NSURLSession.shareSession().dataTaskWithUrl(nsURL) {(data,response,error) in 
print(NSString(data: data, encoding: NSUTF8StringEncoding)) }

“incrementby10”示例与从服务器获取某些数据的实际示例有何关系。我不明白他的意思:“当你从 url 中获取某些内容时,你不会立即获得内容。你可以在下载 url 后调用闭包。”

最佳答案

这是一个异步回调的示例。

异步回调用于在长时间运行的操作(例如网络请求)完成时执行闭包。它们允许我们触发网络请求,传入回调,然后在网络操作正在进行时继续执行其他代码。只有当操作完成时,才会执行闭包,并将服务器返回的数据作为参数传入。

如果我们不使用异步闭包,当我们从服务器获取某些内容时,应用程序将卡住(执行将停止)。这将是一个同步网络请求,并且不会使用它,因为它会导致非常滞后的 UI 和糟糕的用户体验。

NSURLSessiondataTaskWithURL 本质上是一个异步 API,它接受闭包作为参数,并在收到响应时触发它。

<小时/>

异步回调

异步回调网络调用示例(将其添加到 Swift Playground):

import UIKit
import XCPlayground // Only needed for Playground

// Only needed for Playground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

class HTTP {

    class func GET(onSuccess: NSData -> Void ) {

        NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://httpbin.org/get")!, completionHandler: { data, response, error in
            onSuccess(data!)

        }).resume()
    }
}


print("About to fire request")
HTTP.GET({ payload in
    let response = NSString(data: payload, encoding: NSUTF8StringEncoding)
    print("Got network response: \(response)")
})
print("Just fired request")

打印的结果不是您直观地期望的:

About to fire request
Just fired request
Got network response: ...

刚刚触发的请求之前打印得到网络响应:...,因为网络请求是异步执行的。

上述代码的同步版本将产生以下输出:

About to fire request
Got network response: ...
Just fired request

关于swift - 从服务器检索数据时,闭包到底做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36949987/

相关文章:

swift - swift 2 中的错误 URL

swift - 在 Swift 3.0 中将以下 urlString 转换为编码的 urlString

ios - 从多个 View Controller 输入数据时如何更新核心数据

ios - 图像不适合 ImageView

ios - 从本地文件播放声音

javascript - 在 Javascript 中具有自调用函数的范围

php - 您将在何处以及如何(实际上)在 PHP 中使用 Closure 接口(interface)?

swift - 在 RxSwift 中合并两个通知观察者

swift - 在@IBAction 完成之前, View /窗口不会更新

objective-c - 同步块(synchronized block)内的 block ?