Apple的新编程语言Swift如何处理块和异步请求?

时间:2014-06-03 02:55:27

标签: swift

C.f。 Apple在Swift上的网站页面:https://developer.apple.com/swift/

Swift中的块是否像objective-c一样?它们是如何创建和调用的?

如何在Swift中执行异步请求?

在swift中创建与块相关的内存泄漏是否容易?如果是的话,你会如何避免它们?

3 个答案:

答案 0 :(得分:28)

(Objective-)C块的Swift等价物称为闭包。在Swift编程语言书中有关于它们的a whole chapter

根据您使用闭包的上下文,您可以使用非常简洁的语法声明/使用它。例如,可以像这样调用一个签名为(success: Bool, error: NSError) - > Void的完成处理程序的方法:

someMethod(otherParameters: otherValues, completionHandler:{ success, error in
    if !success { NSLog("I am a leaf on the wind: %@", error) }
})

还有一个尾随闭包语法,在闭包基本上提供流控制的情况下可以很好地读取。当你想要真正简短时,你可以删除参数名称(以可读性为代价,但在一些明显的情况下,如下所示)。通常return语句也是隐含的。

myArray.sort { $0 < $1 }
let squares = myArray.map { value in
    value * 2
}    

Swift本身没有任何异步请求,所以你使用现有的API。但是,您可以使用尾随闭包语法:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    // do some async stuff
    NSOperationQueue.mainQueue().addOperationWithBlock {
        // do some main thread stuff stuff
    }
}

在大多数情况下,您不必担心使用Swift闭包创建引用循环,就像使用ObjC块一样。简单地说,捕获语义类似于“只是工作”你想要它的方式对于大多数东西,但足够不同,块/闭包使用的常见模式(例如派遣到后台/主线程和引用{{ 1}}的属性)不会导致循环。

但是,循环仍然是可能的,并且有一个解决方案。这个答案已经有点长了,所以请查看文档中的Strong Reference Cycles for Closures以获得完整的解释。

答案 1 :(得分:8)

Swift中的块称为闭包。它们的操作与块大致相同(虽然更灵活,但在更多地方运行)。使用Swift中的闭包可以实现引用循环,并且可以通过闭包捕获列表来避免。

“Swift为这个问题提供了一个优雅的解决方案,称为闭包捕获列表。但是,在您学习如何使用闭包捕获列表打破强引用循环之前,了解如何导致这样的循环很有用“

摘自:Apple Inc.“The Swift Programming Language。”iBooks。 https://itun.es/us/jEUH0.l

答案 2 :(得分:3)

正如我在另一个问题中所说,你有很多方法可以在Swift中传递一个等效于函数的块。

我发现了三个。

为了理解这一点,我建议你在游乐场测试这段小代码。

func test(function:String -> String) -> String
{
    return function("test")
}

func funcStyle(s:String) -> String
{
    return "FUNC__" + s + "__FUNC"
}
let resultFunc = test(funcStyle)

let blockStyle:(String) -> String = {s in return "BLOCK__" + s + "__BLOCK"}
let resultBlock = test(blockStyle)

let resultAnon = test({(s:String) -> String in return "ANON_" + s + "__ANON" })


println(resultFunc)
println(resultBlock)
println(resultAnon)

更新:匿名功能有两种特殊情况。

首先,可以推断出功能签名,因此您不必重写它。

let resultShortAnon = test({return "ANON_" + $0 + "__ANON" })

第二种特殊情况仅在块是最后一个参数时起作用,它被称为尾随闭包

这是一个例子(与推断签名合并以显示Swift权力)

let resultTrailingClosure = test { return "TRAILCLOS_" + $0 + "__TRAILCLOS" }

最后,作为一个例子:

使用所有这些功能我所做的就是混合尾随闭包和类型推断(为了便于阅读命名)

PFFacebookUtils.logInWithPermissions(permissions) {
    user, error in
    if (!user) {
        println("Uh oh. The user cancelled the Facebook login.")
    } else if (user.isNew) {
        println("User signed up and logged in through Facebook!")
    } else {
        println("User logged in through Facebook!")
    }
}