异步编程对于需要在不可预测网络上通信的应用程序来说是响应式用户界面的必备技术(例如智能手机应用程序)。在等待来自互联网某处的结果返回时,用户界面必须保持响应。
在大多数语言中,应用程序员必须实现自己的状态机(可能使用闭包)来响应异步回调和/或使用锁协调多个线程。这两者都非常容易出错,不适合心脏脆弱的人!
(C#引入了async关键字来帮助解决此问题,只有时间(至少5年)才能证明它是否是一个好的解决方案.)
Swift是否有任何内置支持来协助编写异步代码?
异步编程对于需要在不可预测网络上通信的应用程序来说是响应式用户界面的必备技术(例如智能手机应用程序)。在等待来自互联网某处的结果返回时,用户界面必须保持响应。
在大多数语言中,应用程序员必须实现自己的状态机(可能使用闭包)来响应异步回调和/或使用锁协调多个线程。这两者都非常容易出错,不适合心脏脆弱的人!
(C#引入了async关键字来帮助解决此问题,只有时间(至少5年)才能证明它是否是一个好的解决方案.)
Swift是否有任何内置支持来协助编写异步代码?
虽然这不是一种内置的语言特性,但值得注意的是可以为Swift实现类似于C#的async
/await
, 并且由于在函数调用的最后一个闭包参数中提供了特殊的语法,它甚至看起来可能是该语言的一部分。
如果有人感兴趣,可以在Bitbucket上获取此代码。以下是一些可能性的快速示例:
let task = async { () -> () in
let fetch = async { (t: Task<NSData>) -> NSData in
let req = NSURLRequest(URL: NSURL.URLWithString("http://www.google.com"))
let queue = NSOperationQueue.mainQueue()
var data = NSData!
NSURLConnection.sendAsynchronousRequest(req,
queue:queue,
completionHandler:{ (r: NSURLResponse!, d: NSData!, error: NSError!) -> Void in
data = d
Async.wake(t)
})
Async.suspend()
return data!
}
let data = await(fetch)
let str = NSString(bytes: data.bytes, length: data.length,
encoding: NSUTF8StringEncoding)
println(str)
}
另外,如果你想要类似于@synchronized的功能,请尝试以下代码:
func synchronized(obj: AnyObject, blk:() -> ()) {
objc_sync_enter(obj)
blk()
objc_sync_exit(obj)
}
var str = "A string we can synchronise on"
synchronized(str) {
println("The string is locked here")
}
Swift对于异步编程的方法与Objective C相同:使用Grand Central Dispatch。您可以像在ObjC中一样将闭包传递给gcd dispatch_函数。但是,出于美学原因,您还可以在关闭括号后传递闭包(块):
dispatch_async(dispatch_get_main_queue()) {
println("async hello world")
}
objc_sync_enter()
/objc_sync_exit()
的语法糖。如果你愿意,你可以在 Swift 中这样做,甚至可以添加类似的语法。 - al45tair