2016-07-20 6 views
1

ボタンMaleの下に、2つの完了ハンドラがあります。何らかの理由で、第2のハンドラが第1の完了ハンドラと同時に実行される。私はGrand Central Dispatchに慣れていませんが、GCDを使って最初の完了ハンドラが実行されたときだけ、2番目のハンドラを実行するように設定しています。別のコードブロックが実行された後にのみコードブロックを実行する方法

@IBAction func Male(sender: AnyObject) { 

FIRDatabase.database().reference().child("users").child(self.userdefaults.objectForKey("FBid") as! String).child("anonymous chatting").child("Males").child("Non-Chatting").observeEventType(.Value, withBlock: { (snapshot2: FIRDataSnapshot!) in 

       self.nonChatting = Int(snapshot2.childrenCount) 

       print("yobitch\(self.nonChatting)") 

       }, withCancelBlock: nil) 

//^^^^^^^^^^^^EXECUTE THIS COMPLETION HANDLER FIRST    

    FIRDatabase.database().reference().child("users").child(self.userdefaults.objectForKey("FBid") as! String).child("anonymous chatting").child("Males").child("Non-Chatting").observeEventType(.ChildAdded, withBlock: { (snapshot) in 

       if let dictionary = snapshot.value as? [String: AnyObject] { 

        if self.Malecount < self.listofMaleFriends.count { 
         self.idArray.append(dictionary) 
         self.Malecount += 1} 
     } 

       self.loopCount += 1 
       if self.loopCount == self.listofMaleFriends.count-(self.matchingLoopCount) { 
       self.loopCount = 0 
       self.matchingLoopCount += 1 
        if self.idArray.count == self.listofMaleFriends.count-(self.Othercount){ 
         let randomNumber = Int(arc4random_uniform(UInt32(self.idArray.count))) 
         if self.idArray.isEmpty{ 
         } 
         else{ 

          let Dictionaire = self.idArray[randomNumber] as! [String: AnyObject] 
          let id = Dictionaire["id"] as! String 
          let gender = Dictionaire["gender"] as! String 
          let name = Dictionaire["name"] as! String 
          self.idArray.removeAtIndex(randomNumber) 
          self.Othercount += 1 /* Reduces Male Count*/ 

       let ref = FIRDatabase.database().referenceFromURL("https://game-of-chats-ce897.firebaseio.com/").child("users").child(self.userdefaults.objectForKey("FBid") as! String).child("anonymous chatting").child("Males").child("Chatting").child(id) 
       let refout = FIRDatabase.database().referenceFromURL("https://game-of-chats-ce897.firebaseio.com/").child("users").child(self.userdefaults.objectForKey("FBid") as! String).child("anonymous chatting").child("Males").child("Non-Chatting").child(id) 
       ref.setValue(["id": id, "gender": gender, "name": name]) 
       refout.removeValue() 

        //let user = User() 
        // user.id = self.friendId 
        // user.name = self.friendName 
        // showChatControllerForUser(user) 
        self.user.id = Dictionaire["id"] as! String 
        self.user.name = Dictionaire["name"] as! String 
        //let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout()) 

        // self.(chatLogController, animated: true, completion: nil) 
        //self.navigationController?.pushViewController(chatLogController, animated: true) 
       self.showChatControllerForUser() 

         }}} 

      }, withCancelBlock: nil) 

     } 

答えて

0

dispatch_groupを使用して、2つのタスクを同期させることができます。

  1. dispatch_group_create()を使用してディスパッチグループを作成します。
  2. 各タスクについては、dispatch_group_enter()を呼び出します。
  3. タスクが完了したら、dispatch_group_leave()に電話してください。
  4. dispatch_group_notify()を呼び出して、タスクが完了するまで待ちます。

例:

let node = FIRDatabase.database().reference().child("users").child(self.userdefaults.objectForKey("FBid") as! String).child("anonymous chatting").child("Males").child("Non-Chatting") 

let group = dispatch_group_create() 

// Second handler 
dispatch_group_enter(group) 

node.observeEventType(.Value, 
    withBlock: { (snapshot2: FIRDataSnapshot!) in 
     // Handle event... 
     dispatch_group_leave(group) 
    }, 
    withCancelBlock: nil 
) 

// First handler 
dispatch_group_enter(group) 

node.observeEventType(.ChildAdded, 
    withBlock: { (snapshot) in 
     // Handle event 
     dispatch_group_leave(group) 
    } 
    withCancelBlock: nil 
) 


dispatch_group_notify(group, dispatch_get_main_queue()) { 
    self.showChatControllerForUser() 
} 

ヒント:彼らは取り扱っていたら、そうでない場合は、あなただけの新しい参照にIBActionが呼び出されるたびに保持し続けます、イベントのオブザーバーを削除します。

関連する問題