asynchronous - 如何在 Playground 中运行异步回调

标签 asynchronous callback closures swift swift-playground

许多 Cocoa 和 CocoaTouch 方法都将完成回调实现为 Objective-C 中的 block 和 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 时间轴中看到控制台输出,但是我的完成 block 中的 println 从未被调用...

最佳答案

虽然您可以手动运行运行循环(或者,对于不需要运行循环的异步代码,使用其他等待方法,如分派(dispatch)信号量),但我们在 playgrounds 中提供的“内置”方式等待异步工作是导入 XCPlayground 框架并设置 XCPlaygroundPage.currentPage.needsIndefiniteExecution = true。如果设置了此属性,当您的顶级 Playground 源代码完成时,我们不会在那里停止 Playground ,而是继续旋转主运行循环,因此异步代码有机会运行。我们最终将在默认为 30 秒的超时后终止 playground,但如果您打开辅助编辑器并显示时间轴助手,则可以配置该超时;超时在右下方。

例如,在 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

关于asynchronous - 如何在 Playground 中运行异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24058336/

相关文章:

swift - Swift 的简单闭包示例

go - 编写传递匿名函数作为参数的高阶函数

IOS/AF网络: enqueue two JSON operations and then compare the returned NSArrays

python - 如何向 pointdrawtool 添加 python 回调

c++ - std::bind 和 unique_ptr - 如何只移动?

ios - 从回调函数获取值不起作用

haskell - 以纯/函数式语言(Elm/Haskell)实现自引用/指针

c# - C# 中的异步实现与 F# 中的实现相同吗?

asp.net - ASP.NET 中的异步调用

c# - 何时使用 System.Threading.ThreadPool 以及何时使用众多自定义线程池之一?