Swift Tips 023 - Working on async code in a playground

每天了解一点不一样的 Swift 小知识

代码截图

小笔记

这段代码在说什么

为了使 Playground 具有延时运行的本领,我们需要引入 Playground 的 “扩展包” PlaygroundSupport 框架。现在这个框架中包含了几个与 Playground 的行为交互以及控制 Playground 特性的 API,其中就包括使 Playground 能延时执行的黑魔法,PlaygroundPage 和 needsIndefiniteExecution。

Playground 里的异步执行

Playground 中的代码是顶层代码(top-level code),也就是它是在于全局作用域中的。这些代码将会从上到下执行,并在执行完毕之后立即停止。

我们的异步回调代码一般都无法在程序结束之前获得执行,因此如果我们在 Playground 执行网络,或者其它耗时的异步操作,都无法获得我们想要的结果。

为了让程序在代码执行结束后继续执行,我们可以使用如下代码:

PlaygroundPage.current.needsIndefiniteExecution = true

这句代码会让 Playground 永远执行下去 ,当我们获取了需要的结果后,可以使用 PlaygroundPage.current.finishExecution() 停止 Playground 的执行:

import PlaygroundSupport
import Foundation
import UIKit
PlaygroundPage.current.needsIndefiniteExecution = true
let url = URL(string: "http://xxx/image/png")!
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, _, _) in
let image = UIImage(data: data!)
PlaygroundPage.current.finishExecution()
}
task.resume()

关于 Playground 的 Sources 目录

通常情况下,我们直接在 Playground 上面写代码,然后编译器会实时编译我们代码,并将结果显示出来。这很好,我们可以实时得到代码的反馈。

但是这也会产生一个问题,如果我们写了一个函数,或者自定义了一个 view,这部分代码一般情况下是不会变的,而编译器却会一次又一次地去编译这些代码,最终的结果就是导致效率的低下。

这时,Sources 目录就派上用场了,使用 Cmd + 1 打开项目导航栏,可以看到一个 Sources 目录。放到此目录下的源文件会被编译成 module 并自动导入到 Playground 中,并且这个编译只会进行一次(或者我们对该目录下的文件进行修改的时候),而非每次你敲入一个字母的时候就编译一次。 这将会大大提高代码执行的效率。

但是请注意!

由于此目录下的文件都是被编译成模块导入的,只有被设置成 public 的类型,属性或方法才能在 Playground 中使用。

重看 Xcode Swift Playground

Swift 语言是苹果在 WWDC 14 上正式发布的,与之同时发布的 Xcode 6 中也第一次集成了 Playground 功能。两年后的 WWDC 16 上,苹果发布了 iPad 专有的 Swift Playground 软件,帮助大家更好地学习使用 Swift 语言。到今年,Xcode Playground 已经 5 岁了。

这些年 Playground 一直进步,这一点可以在每年的 WWDC 上得到验证,因为你总能发现一些关于它的独立 Session。

今年关于 Playground 的 Session 叫做 Swift Playgrounds 3,通过这个 session 我们可以明显感觉到使用 iPad 上的 Playground 进行编程是十分便利的,也非常有趣,因为这种开发体验是独一无二的,它让开发者与硬件的交互变得更加紧密。

让我们假设一个场景,如果我们要开发一个与 加速计、陀螺仪相关的 Demo!

通常我们需要在 Xcode 里面编写相关代码,注册开发者账号,连接真机,编译代码,等待安装,才能开始真正调试。想想这一连串的步骤就让人头大,不是么?

而现在,只需要在 Playground 上编写即可直接运行调试。

所以说了这么多,不妨把你吃灰已久的 iPad 拿出来把玩一下吧,相信你一定会爱上 Swift Playground 的!