如何在调度块中获取返回值?

LON*_*LiE 3 swift swift3

如何从异步调度块获取返回值?

我想出了这个示例代码:

if let url = URL(string: "https://google.com/") {
    let data: Data? = ***SOME_ASYNC_AWAIT_DISPATCH_GROUP<T>*** { return try? Data(contentsOf: url) }
    print("Downloaded Data: \(data)")
}
Run Code Online (Sandbox Code Playgroud)

目标:在这里,我希望异步调用生成结果并将其存储到data常量,以便我可以使用它.

Amr*_*ari 8

我很简单,使用完成方法来完成此操作.测试功能从后台线程中的url下载数据,并在下载完成块运行后,它返回下载的数据,它可以在任何格式中将其转换为您的格式.

func UpdateUI(){

        test { (data) in
          //data is value return by test function
            DispatchQueue.main.async {
                // Update UI
                //do task what you want.
                // run on the main queue, after the previous code in outer block
            }
        }
    }

    func test (returnCompletion: @escaping (AnyObject) -> () ){

        let url = URL(string: "https://google.com/")
        DispatchQueue.global(qos: .background).async {
            // Background work
            let data = try? Data(contentsOf: url!)
            // convert the data in you formate. here i am using anyobject.
            returnCompletion(data as AnyObject)
        }
    }
Run Code Online (Sandbox Code Playgroud)

希望它会对你有所帮助.


LON*_*LiE 4

我找到了解决方案。

// REFERENCED TO: https://gist.github.com/kylesluder/478bf8fd8232bc90eabd
struct Await<T> {
    fileprivate let group: DispatchGroup
    fileprivate let getResult: () -> T
    @discardableResult func await() -> T { return getResult() }
}
func async<T>(_ queue: DispatchQueue = DispatchQueue.global() , _ block: @escaping () -> T) -> Await<T> {
    let group = DispatchGroup()
    var result: T?
    group.enter()
    queue.async(group: group) { result = block(); group.leave() }
    group.wait()
    return Await(group: group, getResult: { return result! })
}
Run Code Online (Sandbox Code Playgroud)

打电话来喜欢这个。

let data = async{ return try? Data(contentsOf: someUrl) }.await()
Run Code Online (Sandbox Code Playgroud)

或者

更简单:

@discardableResult func async<T>(_ block: @escaping () -> T) -> T {
    let queue = DispatchQueue.global()
    let group = DispatchGroup()
    var result: T?
    group.enter()
    queue.async(group: group) { result = block(); group.leave(); }
    group.wait()

    return result!
}
Run Code Online (Sandbox Code Playgroud)

打电话来喜欢这个。

let data = async{ return try? Data(contentsOf: someUrl) }
Run Code Online (Sandbox Code Playgroud)

(感谢您编辑我的问题,西曼。)

  • 使用“DispathGroup”时要非常小心 - 它们很可能会导致死锁。 (2认同)