2016-04-24 36 views
6

私は基本的に、私のviewDidLoadで呼び出されているメソッドにする必要があります。最初のものはユーザーの検索設定を取得し、その設定を変数の先頭に保存します。その後、2番目の関数でこれらの変数にアクセスして作業したいと思います。しかし、2番目の関数で変数にアクセスしたいときは、変数は常にnilです。iOS/Swiftで関数が終了するまで待つ方法

viewDidLoadを調整する必要があるので、2番目の機能は1回だけ実行され、データリクエストは正常に実行されます。

ディスパッチ_アシンクまたは完了ハンドラでこれまでの情報を読み込んでいます。たぶん誰かが私のviewDidLoadで使用できるコードを投稿し、それを動作させることができますか?

+5

あなたがそう言っていないが、getThSearchLocationAndRangeが非同期でなければなりませんか?あなたが待ってはいけない場合は、GUIをハングアップさせるでしょう。代わりに、最初の関数をパラメータとして完成ブロックにし、ブロック本体として2番目の関数を置くこともできます。それ以外の方法もあります。 – Gruntcakes

+0

ええ、それがありました!私にそれを示すサンプルコードがありますか?しかし、それは完了ハンドラで他の投稿に見たアイデアでもありました! – Mattk90

+0

getTheSearchLocationAndRangeにディスパッチ機能がありますか? – FredericP

答えて

1

オーケー、私は解決策を見つけました。私は基本的に最初の関数の最後に関数を呼び出しました。そこで、基本的

var searchLocation = String() 
    var searchLocationCoordinates = [String:Double]() 
    var searchRange = Int() 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Gets the user's search preference 
     getTheSearchLocationAndRange() 
    } 

    func getTheSearchLocationAndRange() { 
    // Code for getTheSearchLocationAndRange() 

    loadDataFromDatabase() 
    } 

    func loadDataFromDatabase(){ 
    // Code for loadDataFromDatabase() 
    } 
+1

この問題は、 'getTheSearchLocationAndRange()'関数が、 'loadDataFromDatabase'を呼び出すと仮定されている場合を除き、あまり有用ではないということです。メソッドの柔軟性を高めるには、補完ブロックメソッドを使用します。 – milesper

+0

私はその点に同意します。私の場合は、両方の機能を別々にする必要はありません。それで、私はこれのようにそれを解決することができると思います。しかし、私はあなたの信用を与える、あなたは解決策は、プログラム的に優れているかもしれない!ハハ – Mattk90

6

スウィフトクロージャを使用することができます。彼らはそれのために作られています。

アップルガイドを参照してください:Closures

ここでは、あなたの特定のケースで必要なコードです。

完了済みはクローズです。 getTheSearchLocationAndRange()が呼び出されると、そのコードは関数のすべての処理が完了するのを待つcompleted()行まで実行されます。プロセスが終了すると(例えば、ダウンロード)、completed()は、getTheSearchLocationAndRange {() ->() inで定義されたコードをアクティブにするクロージャを呼び出します。したがって、loadDataFromDatabase()は、getTheSearchLocationAndRange()が完全に実行を終了し、データが存在する場合(nilでない場合)にのみ呼び出されます。私は、これはあなたの問題を解決し、ところで、あなたの質問:)

に答えを期待

var searchLocation = String() 
    var searchLocationCoordinates = [String:Double]() 
    var searchRange = Int() 
    typealias FinishedDownload =() ->() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     getTheSearchLocationAndRange() 
    } 

    func getTheSearchLocationAndRange(completed: FinishedDownload) { 

      // Code for searching Location Range HERE 

      completed() 
    } 

    getTheSearchLocationAndRange {() ->() in 
     loadDataFromDatabase() 
    } 

は、一部を「ぶら下げあなたのGUIを残す」について、Alamofireは自動的にあなたのためにこれを引き受け。 Alamofireを使用しない場合は、非同期要求をバックグラウンドスレッドに手動で割り当てて、GUIが応答しなくなるようにする必要があります。

+0

返す必要があるgetTheSearchLocationAndRangeのパラメータがあるとどうなるでしょうか – Sam

3

私はデモプロジェクトを作成し、非同期ネットワークダウンロードの処理をシミュレートするGitHubに投稿しました。 DuncanMC/SwiftCompletionHandlersをご覧ください。

具体的には、このスレッドが話していることをほぼ正確に行うメソッドasyncFetchImage()を見てください。非同期メソッドを内部的に使用し、非同期ロードが完了した後に完了ブロックを呼び出します。

これは一般的なパターンです。完了ブロック/クロージャをとるメソッドを記述します。内部的には、そのメソッドが必要な非同期関数を呼び出してから、非同期メソッド呼び出しの完了クロージャ内から完了クロージャを呼び出します。

機能asyncFetchImageは、次のようになります。

func asyncFetchImage(imageName imageName: String, 
    completion: (
    image: UIImage?, 
    status: String) ->()) 
{ 
    print("Entering \(#function)") 

    //Simulate a network operation by waiting a few seconds before loading an image 
    let nSecDispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))) 
    let queue = dispatch_get_main_queue() 
    dispatch_after(nSecDispatchTime, queue) 
    { 
    () -> Void in 
     let result = UIImage(named: imageName) 
     print("Loading image in background") 
     let status = result != nil ? "image loaded" : "Error loading image" 
     print("About to call completion handler") 
     completion(image: result, status: status) 
    } 
    print("Leaving \(#function)") 
} 
関連する問題