2017-07-07 6 views
0

@IBaction func loginの文中に私はstartObserving()と呼んでいます。メインスレッドで実行されないのはなぜですか?
この文print("executed")は、self.startObservingDB(callback: { (snapValue) inのコードがelse文で評価される前に実行されます。 FirebaseからsnapValueを受け取る前に、startObservingDBが復帰しないようにします。 else文でstartObservingDBをどのようにしてFirebaseがそのタスクを完了してから実行を続けるのを待つことができますか?タスクを順番に実行する方法は? Swift3

@IBAction func logIn(_ sender: AnyObject) { 

    FIRAuth.auth()?.signIn(withEmail: email.text!, password: password.text!, completion: { (authData, error) in 

    if error != nil { 
      // 
     } else { 
     self.startObservingDB(callback: { (snapValue) in 
     if snapValue != nil { 
      print("should segue") 
       self.performSegue(withIdentifier: "LogInToTabBarController", sender: self) 
        } 
       })//end of startObservingDB 


//prints before code in else statement, inside self.startObservingDB(callback: { (snapValue) is evaluated 
print("executed") 
     } 
    }) 
} 



func startObservingDB(callback:@escaping ((_ snapShot:FIRDataSnapshot?) -> Void)){ 
    // check if user is singed in 
    guard let uid = FIRAuth.auth()?.currentUser?.uid else { 
     return 
    } 

    dbRef.child(uid).child("profile").observeSingleEvent(of: .value, with: { (snapshot: FIRDataSnapshot) in 

     //pass snapshot vale to callback closure so as to make the values available when calling startObservingDB 
     callback(snapshot.value as? FIRDataSnapshot) 


    }, withCancel: { (Error:Any) in 
     print("Error firebase \(Error)") 
     print("You are not a cleaner") 

    }) 
    dbRef.removeAllObservers() 
} // end of startObserving 

答えて

0

startObservingDB への呼び出しは、同じスレッドで起こっです。

ただし、observeSingleEventの呼び出しでコールバックが発生することがわかります。これは、内部的にこの呼び出しが新しいバックグラウンドスレッドを開始するためです。そのメソッドは、完了すると復帰し、コールバックを呼び出します。

だから、あなたが見ている一連のイベントは次のとおりです。

  • スレッドA:startObservingDBは
  • スレッドAを開始:開始はobserveSingleEvent
  • スレッドのための内部仕事をして:observeSingleEventは
  • スレッドBを開始A:observeSingleEventが返す
  • スレッドA:startObservingDBは
  • を返します。
  • スレッドA:print( "executed observeSingleEventの "と
  • スレッドB「)を
  • スレッドB:observeSingleEvent
  • スレッドBのための内部仕事をして仕上げからコールバックを実行":としてコールバック(snapshot.valueを実行しますか? FIRDataSnapshot)
  • スレッドB:プリント( "セグエすべき")
  • スレッドB:performSegue
+0

は、どのように私は私の方法startObservingDBは、スレッドB 'まで待機することができます:コールバック(snapshot.valueなどを実行FIRDataSnapshot? ) '終了しますか?私は 'self.startObservingDB(コールバック:{(snapValue)in'}の中で' if snapValue!= nil'をチェックする必要があり、これが起きるためにfirebaseが作業を終了するまで 'startObservingDB'を待たなければなりません。ありがとうございました – bibscy

+0

ブロックがどのように動作しているか誤解していると思いますが、あなたは既に言及した動作を得ています。 'callback(FIRDataSnapshotとしてのsnapshot.value)'が実行されると、この呼び出しは 'self.startObservingDB(コールバック:{(snapValue)in'です。メソッドを呼び出すのと同じコードで、そのメソッドでコードを実行します。 –

関連する問題