私は本当にスレッディングに慣れていて、終日読んでいます。何らかの理由で他のコードが実行される前にデータがロードされていないのですが私のfirebaseデータベースが値の更新を待たずにいる理由
基本的に私は配列に書き込むキーを持つすべての値を必要とします。最初にロードする必要があります。だから私はチェックして、私が更新しているキーが存在し、私が抽出しているキーは多分まだ値が存在しないが、キーが行うことを確認します。
問題はコードがメソッドを高速化することです。どのように私は私のfirebaseそれまでは、メインスレッドの待ち時間が、私は以下のことを試してみましたデータをロードしていますが、それはここで
を動作していないようになるだろうと、私のコードは、以下の関数が値を更新し
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let alertController = UIAlertController(title: "Accept Bet", message: "Match the bet of " + amountBets[indexPath.row], preferredStyle: .alert)
let okButton = UIAlertAction(title: "No", style: .default, handler: { (action) -> Void in
print("Ok button tapped")
})
let yesButton = UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
// let them know to wait a second or the bet won't go through
var waitController = UIAlertController(title: "Please Wait", message: "You must wait for the bet to go through", preferredStyle: .alert)
self.present(waitController, animated: true, completion: nil)
//take away that bitches money
self.takeAwayMoney(self.amountBets[indexPath.row], completion: { (result: Bool?) in
guard let boolResult = result else {
return
}
if boolResult == true {
self.updateBet(indexPath.row, completion: {(result: String?) in
guard let resultRecieved = result else {
return
}
print(self.opposingUserNames)
//let delayInSeconds = 7.0 // 1
//DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { // 2
self.dismiss(animated: true, completion: nil)
let successController = UIAlertController(title: "Success", message: "You have made a bet with " + self.opposingUserNames!, preferredStyle: .alert)
let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
successController.addAction(okButt)
self.present(successController, animated: true, completion: nil)
//lastly delete the opposing UserName
print(self.opposingUserNames)
self.amountBets.remove(at: indexPath.row)
self.tableView.reloadData()
print("Second")
print(self.opposingUserNames)
//}
})
} else {
return
}
})
//then delete that cell and do another pop up that says successful
// check if value is yes or no in the database
})
alertController.addAction(okButton)
alertController.addAction(yesButton)
present(alertController, animated: true, completion: nil)
}
あるOpposingUsernameそれは私が以前持っていた論理エラーを切り出して、今アプリは私のwaitAlertViewControllerにハングアップし、この更新されたコードを持つように
func updateBet(_ index: Int, completion: @escaping (_ something: String?) -> Void) {
let userID = FIRAuth.auth()?.currentUser?.uid
datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
// ...
self.datRef.child("Bets").observe(.childAdded, with: { snapshot in
//
// this is the unique identifier of the bet. eg, -Kfx81GvUxoHpmmMwJ9P
guard let dict = snapshot.value as? [String: AnyHashable] else {
print("failed to get dictionary from Bets.\(self.userName)")
return
}
let values = ["OpposingUsername": self.userName,"Show": "no"]
self.datRef.child("Bets").child(self.tieBetToUser[index]).updateChildValues(values)
// now get the opposing username which is just the Username registered to that specific bet
self.datRef.child("Bets").child(self.tieBetToUser[index]).observe(.childAdded, with: { snapshot in
guard let dict2 = snapshot.value as? [String: AnyHashable] else {
return
}
let userNameOfOtherPlayer = dict2["Username"] as? String
self.opposingUserNames = userNameOfOtherPlayer!
completion(self.opposingUserNames)
})
})
}) { (error) in
print(error.localizedDescription)
}
}
OKを示しています。理由は分かりません。それはfirebaseデータベースのベットを更新しているので、私はそのコードを実行していることを知っていますが、そのコードを実行することは決して完全ではありません。申し訳ありませんbibscy私はあなたがそれを呼び出すとき、それはすぐに返すことを意味し、asyncronous関数であるあなたが
完了ハンドラは、あなたがより良い
ObserveSingleEvent(OF_)それらを理解すれば、かなり強力で、今何を意味するかを見、それはありません中括弧内のコードを実行しないで、バックグラウンドスレッドで作業を続け、実行が終了すると、結果は 'completion:@escaping(_ result')になります。現在の設定では、完了ハンドラが呼び出されますあなたが 'didSelectRowAt indexPath'で' getOpoosingUserNames'を呼び出すときには、self.updateBet(indexPath.row、completion:{(result:String)in)と文字列( "success" 'の後に' – bibscy
あなたはあなたが望む結果を得ることができ、現在は' opposingUserNames'を保持します。その後、tableViewをリロードすることができます。もしあなたがそれを働かせたら教えてください。 – bibscy
私の答えは[Firebase is asynchronous](http://stackoverflow.com/questions/37104816/finish-asynchronous-task-in-firebase-with-swift/37124220#37124220)をご覧ください。クロージャ内のコードが実行される前に、クロージャの外側のコード*が実行されます。 Firebase関数から返されたデータを処理する場合は、クロージャ内で*行う必要があります。 – Jay