一尘不染

如何在Playground中运行异步回调

swift

许多Cocoa和CocoaTouch方法都将完成回调实现为Objective-
C中的块,而实现为Swift中的Closures。但是,在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在我的完成块中从未调用过…


阅读 324

收藏
2020-07-07

共1个答案

一尘不染

虽然您可以手动运行一个运行循环(或者,对于不需要运行循环的异步代码,请使用其他等待方法,例如调度信号量),但我们在操场上提供的“内置”方法是等待异步工作导入XCPlayground框架并设置`XCPlaygroundPage.currentPage.needsIndefiniteExecution

true`。如果设置了此属性,则在您的顶级游乐场源完成时,我们将继续旋转主运行循环,而不是在那里停止游乐场,因此异步代码有机会运行。我们最终将在默认为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
2020-07-07