提供给异步调用的 Swift 闭包不接受任何参数也不返回任何参数

标签 swift multithreading asynchronous closures

在 iTunesU 的 CS193P 斯坦福讲座中,讲师在第 8 课 30:14 提到多线程,您提供给异步调用的闭包“不接受任何参数并且不返回任何参数”。这让我感到惊讶,因为不久之后他给出了一个 iOS 方法的示例 (37:01),其中闭包能够返回参数,即:

let task = session.dataTask(with: url) { (data: Data?, response, error ) in  ...

还有许多其他 iOS 方法似乎会向其完成闭包返回参数。我在这里错过了什么吗?为什么异步调用提供的闭包不能以与上面的 dataTask 调用类似的方式返回参数。

最佳答案

dataTask(with:)DispatchQueueasync 不同。

首先,请记住您使用的是 trailing closure .当函数的最后一个参数是闭包(即代码“ block ”)时,闭包可以放在括号之外。以下代码使用了尾随闭包语法:

someQueue.async {
    //do something
}

等价于下面的代码,不使用尾随闭包语法:

someQueue.async(execute: {
    //do something
})

此外,请记住闭包不会“返回”参数,它们接受 参数。参数是闭包的输入,而返回值是闭包的输出。


The function signature for DispatchQueue's async is:

func async(
    group: DispatchGroup? = default, 
    qos: DispatchQoS = default, 
    flags: DispatchWorkItemFlags = default, 
    execute work: @escaping () -> Void
)

groupqosflags都有默认值,这里可以忽略。重要的部分是execute参数,其类型为@escaping() -> Void。这意味着“一个不带参数并返回 Void(即没有值)的闭包。”


The function signature for URLSession's dataTask method is:

func dataTask(
    with request: URLRequest, 
    completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void
) -> URLSessionDataTask

completionHandler@escaping (Data?, URLResponse?, Error?) -> Void 类型,这意味着它接受三个参数(一个可选的 Data 、一个可选的 URLResponse 和一个可选的 Error)并返回 Void


这两个函数都接受闭包作为参数,但它们接受具有不同签名的闭包。 async 接受一个不接受任何参数的闭包,但是 dataTask 接受一个接受三个参数的闭包。这些功能中的任何一个都没有什么“神奇”之处;它们只是接受闭包,如果愿意,您可以编写自己的函数来接受闭包。

关于提供给异步调用的 Swift 闭包不接受任何参数也不返回任何参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43058062/

相关文章:

Java Thread Good Practice 这个呀?

c# - 如何在不阻塞主线程的情况下将 Thread.Sleep 与 Task.Run 一起使用

javascript - 在 for 循环中异步等待

ios - 从 NSData 中检索 SecKey

swift - 如何使用代码注释画线?

swift - 格式化字符串后出现意外结果

java - 借助 2 个线程打印自然序列(1 个线程打印偶数,第 2 个线程打印奇数)

java线程: producer - consumer

c# - 此 MSDN 示例中 Lazy<T> 的用途

ios - 延迟 : Swift 3 从 SuperView 中删除 View