本文介绍了如何在 Playground 中运行异步回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多 Cocoa 和 CocoaTouch 方法的完成回调在 Objective-C 中实现为块,在 Swift 中实现为闭包.但是,在 Playground 中尝试这些时,永远不会调用完成.例如:

Many Cocoa and CocoaTouch methods have completion callbacks implemented as blocks in Objective-C and Closures in Swift. However, when trying these out in Playground, the completion is never called. For example:

// 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 永远不会被调用......

I can see the console output in my Playground timeline, but the println in my completion block are never called...

推荐答案

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

While you can run a run loop manually (or, for asynchronous code that doesn't require a run loop, use other waiting methods like dispatch semaphores), the "built-in" way we provide in playgrounds to wait for asynchronous work is to import the XCPlayground framework and set XCPlaygroundPage.currentPage.needsIndefiniteExecution = true. If this property has been set, when your top level playground source finishes, instead of stopping the playground there we will continue to spin the main run loop, so asynchronous code has a chance to run. We will eventually terminate the playground after a timeout which defaults to 30 seconds, but which can be configured if you open the assistant editor and show the timeline assistant; the timeout is in the lower-right.

例如,在 Swift 3 中(使用 URLSession 而不是 NSURLConnection):

For example, in Swift 3 (using URLSession instead of 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 中:

Or in 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

这篇关于如何在 Playground 中运行异步回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 04:39