2016-11-30 76 views
2

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

我想出了这个示例代码:

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)") 
} 

目标:在这里,我想异步调用产生的结果,并将其存储到data不变,这样我可以使用它。

回答

1

我找到了解决方案。

// 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! }) 
} 

打电话来这样。

let data = async{ return try? Data(contentsOf: someUrl) }.await() 

OR

更简单:

@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! 
} 

呼叫喜欢这个。

let data = async{ return try? Data(contentsOf: someUrl) } 

(并感谢编辑我的问题,希曼。)

2

我用简单的方法完成这样做。测试函数在后台线程中从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) 
     } 
    } 

希望它能帮助你。

+0

感谢您的回答。 但我希望代码很容易调用。 – LONELiE

+0

不使用完成处理程序返回值并不是不可能的,我给你简单的答案。 –