2017-09-30 6 views
1

Parseサーバーのデータを持つ変数をクラスのすぐ下に宣言された変数にロードするクエリがあります。変数をクエリ関数内のコンソールに出力すると、正しく出力されますが、関数の外で呼び出したり印刷したりすると、変数は空になります。私がどこに間違っているのか?変数がクラスの後で宣言されていても、クエリ関数の外部の変数にアクセスすることができません

変数宣言:

class AddTaskViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate { 
var varCost = "" 

クエリ負荷変数:

let varCostQuery = PFQuery(className: "Class1") 
varCostQuery.findObjectsInBackground(block: { (objects, error) in 
    if error != nil { 
     print(error!) 
    } else { 
     varCostQuery.whereKey("Header", equalTo: self.HeaderSelection.text) 
     varCostQuery.findObjectsInBackground(block: { (objects, error) in 
      for object in objects! { 
       self.varCost = object["pricePerUnit"] as! String 
       print(self.varCost) //Option1 
      } 
     }) 
    } 
}) 
print(varCost) //Option2 

私はオプション1を印刷するとき、私が探しているまさにのように、私はデータを取得し、私はオプション2を印刷したりしようとすると、このレベルで変数varCostを使用すると、変数が更新されていないような""が得られます。

答えて

1

これは、findObjectsInBackgroundメソッドに渡されるコードが、のオブジェクトがすべて見つかった場合に実行されるコードであるために発生します。

このコードはオブジェクトが見つかったときにのみ呼び出されるため、時間がかかることがあるため、このコードはオブジェクトが見つかるまで待機するためにバックグラウンドキューに送信されます。

私たちのコードの残りの部分を一時停止してこれを待ってはいけません!プログラムを遅くするほど遅くなります。したがって、プログラムは完了するまでこのブロックを過ぎて続きます。だからオプション2は空です。findObjectsInBackgroundにはまだオブジェクトを取得する時間がありませんでしたので、コードはすぐにオプション2にジャンプしました。

オブジェクトが最終的に見つかった場合、コードブロックが呼び出され、オプション1が印刷されます。

これは、self.varCostがこのブロック内で正しい値を持つことができることを意味します(またはクロージャ、Swiftで呼び出されるため)。

+0

ああ、意味があります。どのようにそれを修正するための推奨事項?私は、変更を行う時間を与えるために最後のクエリの後に1秒の休止を置くことができ、それはおそらくUXにあまり影響しませんでしたが、私はより良いオプションを検討することを嬉しく思います。 – tmcgee

+1

@tmcgeeこのオブジェクトの所見がどのくらいの時間を取るか分からないので、1秒の休止を入れるのは良い習慣ではありません。ブロック内から 'self.varCost'をパラメータとして関数を呼び出す方がよいでしょう。この関数内で' self.varCost'を使って好きなことをすることができます。**あなたは** 100%確実です**それは正しい値です。 –

+0

サンプルへのリンクがありますか?静的な一時停止よりはるかに良いアプローチのように聞こえる。一時的に問題を解決することができるかどうかを確認するために一時停止してみましたが、それはまだ印刷されています。 :/ – tmcgee

関連する問題