2016-11-30 4 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

完了ハンドラを使わずに値を返すことは不可能ではありません。私はあなたに簡単な答えを与えました。 –

関連する問題