许多 Cocoa 和 CocoaTouch 方法都具有在 Objective-C 中作为块实现的完成回调以及在 Swift 中作为闭包实现的回调。然而,当在 Playground 中尝试这些时,永远不会调用完成。例如:
// Playground - noun: a place where people can play
import Cocoa
import XCPlayground
let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.currentQueue() {
response, maybeData, error in
// This block never gets called?
if let data = maybeData {
let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
println(contents)
} else {
println(error.localizedDescription)
}
}
我可以在 Playground 时间轴中看到控制台输出,但是println
在我的完成块中从未被调用过......
虽然您可以手动运行运行循环(或者,对于不需要运行循环的异步代码,可以使用调度信号量等其他等待方法),但我们在 Playground 中提供的等待异步工作的“内置”方式是导入XCPlayground
框架和集合XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
。如果已设置此属性,则当您的顶级 Playground 源完成时,我们将继续旋转主运行循环,而不是停止 Playground,因此异步代码有机会运行。我们最终将在超时后终止 Playground,超时默认为 30 秒,但如果您打开助理编辑器并显示时间轴助理,则可以配置该超时;超时位于右下角。
例如,在 Swift 3 中(使用URLSession
代替NSURLConnection
):
import UIKit
import PlaygroundSupport
let url = URL(string: "http://stackoverflow.com")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
let contents = String(data: data, encoding: .utf8)
print(contents!)
}.resume()
PlaygroundPage.current.needsIndefiniteExecution = true
或者在 Swift 2 中:
import UIKit
import XCPlayground
let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue()) { response, maybeData, error in
if let data = maybeData {
let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
println(contents)
} else {
println(error.localizedDescription)
}
}
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)