2017-09-13 9 views
-1

私は以下の関数を使用しています。私はその非同期関数からのデータが欲しいですが、fullResolutionImageData関数の外でデータを使用しようとするとnilになります。だから私はコールバックを書く必要があります。しかし、私はコールバックを書く方法を知らない。他の人がデータを他の場所にアクセスできるように、以下の非同期関数のコールバックを書く方法を私に見せてもらえますか? fullResolutionImageData非同期機能以外のファイルにアクセスできるようにコールバックを書く方法を教えてください。私はこの機能以下の非同期関数のコールバックを書くには

class ViewController: UIViewController{ 
    func buttonAction(sender:UIButton!){ 
     var photos2: [ImageSource]? 
     var files : [Data] = [] 
     let _ = self.photos2?.map ({completion: path in 
      path.fullResolutionImageData{ data in 
       files.append(data) --> (prints 2) 
      } 
     }) 
     print("(files.count)") --> (prints 0 How do I write callback?) 
    } 
} 
+0

あなたの実装を使用し廃棄されている場合はマップを使用して、その後、foreachループを使用することは理にかなっていますこの構造の方法でwebservice:https://stackoverflow.com/a/46081822/3400991このリンクの指示に従います –

+0

プロトコル/デリゲートパターンを使用して、あなたの 'ViewController' onc画像処理が終了する。 – toddg

+0

あなたはこれを編集する方法を教えてください。私は少し混乱しています。私はコーディングが新しく、多くのプロトコルを学んだことはありません – Useruuu

答えて

0

を使用するアクションを持っている私のビューコントローラで

public func fullResolutionImageData(completion: @escaping (Data?) ->()) { 
    SharedQueues.imageProcessingQueue.addOperation { [path] in 
     let data = try? Data(contentsOf: URL(fileURLWithPath: path)) 
     DispatchQueue.main.async { 
      completion(data) 
     } 
    } 
} 

uが必要なのは、派遣グループです。説明の

func buttonAction(sender:UIButton!){ 
     var photos2: [ImageSource]? 
     var files : [Data] = [] 

     let myGroup = DispatchGroup() 
     let _ = self.photos2?.map ({completion: path in 
      myGroup.enter() 
      path.fullResolutionImageData{ data in 
       files.append(data) --> (prints 2) 
       myGroup.leave() 
      } 
     }) 

     myGroup.notify(queue: DispatchQueue.main) { // 2 
      print("(files.count)") 
     } 
    } 

リトルビット:

ディスパッチグループは、複数の非同期タスクの完了を監視するために使用されます。あなたのケースでは、あなたがバックグラウンドスレッドで実行しているファイルパスからデータを取得するように。注意すべき

もの:

グループは関係なく、それはその目標にか成功したかどうかのグループを残すべきではない入るひとつひとつの作業。グループに入ったタスクのいずれかが終了しなかった場合、そのスレッドは永遠にブロックされます。したがって、fullResolutionImageDataが必ず完了ブロックを実行するようにしてください!

EDIT:

最後にコメントでDavidで指摘したように、それはuが結果にしたがって

func buttonAction(sender:UIButton!){ 
     var photos2: [ImageSource]? 
     var files : [Data] = [] 

     let myGroup = DispatchGroup() 
     photos2?.forEach{ path in 
      myGroup.enter() 
      path.fullResolutionImageData{ data in 
       files.append(data) --> (prints 2) 
       myGroup.leave() 
      } 
     } 

     myGroup.notify(queue: DispatchQueue.main) { // 2 

     } 
    } 
+0

したがって、関数の外部でファイルの数にアクセスするにはどうすればよいですか。それはdispatch.notifyにありますか? – Useruuu

+1

OPからその部分をコピーしたばかりですが、戻り値を破棄する場合は 'map'を使用しないでください。構文を保持したい場合は 'forEach'を使います。 –

+0

@useruuu:はいサー!その答えを注意深く読んでください。 DispatchGroupは、それを使用する方法を知っている限り、驚くべきツールです:D –

関連する問題