2016-04-28 7 views
-1
  • 私の問題:

SubViewControllerは、そのビューをロードする前に、私は、Alamofireを通じて、サーバーからデータをロードしようとしています。コードを書いた後、私はAlamofireの非同期機能の問題を解決できませんでした。 Alamofireがジョブを終了する前に、SubViewControllerに常にビューがロードされます。私のコードAlamofireが仕事を終えた後の表示方法

  • パート:

ParentViewController:

PrepareForSegue()を通じてSubViewControllerする方法をリードします。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 

    if segue.identifier == "CellDetailSegue" { 
     if let indexPaths = self.dateCollectionView.indexPathsForSelectedItems() { 
      let subViewController = segue.destinationViewController as! SubViewConroller 
    } 
} 

SubViewController:

テストデータがviewDidLoad()print()によってロードされ、dataRequest()

class SubViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    var availablePeriods401 = [String]() 
    var availablePeriods403 = [String]() 
    var availablePeriods405 = [String]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.dataRequest(self.availablePeriods401) 
     self.dataRequest(self.availablePeriods403) 
     self.dataRequest(self.availablePeriods405) 
     print(self.availablePeriods401.count) 
     print(self.availablePeriods403.count) 
     print(self.availablePeriods405.count)  
    } 

    func dataRequest(_ target: [String]) { 
     Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { 
      . 
      . 
      . 
     target = Result 
     } 
    } 

} 
  • viewWillAppear()における問題の説明によってデータをロードされたかどうか:

ビューがロードされた後、SubViewControllerの3つの変数に有効な値を割り当てることはできません。

3出力の結果がすべて0

あるしかし、私はdataRequest()print()を設定した場合、私は有効なカウントを取得することができます。

  • 私の質問:

がどのようにAlamofireはその仕事を終えていることを確認してくださいするには?

ここで私はAlamofire Request機能を置くべきですか? viewWillApper()viewDidApper()

ParentViewControllerのPrepareForSegue()でジョブの要求を完了する必要がありますか?


どのようにこの問題を解決を教えてください。

あなたのガイドと時間に大きな感謝。

イーサン・ジョー

答えて

-1

まず、偽

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 

    if segue.identifier == "CellDetailSegue" && boolVar { 
     if let indexPaths =  self.dateCollectionView.indexPathsForSelectedItems() { 
      let subViewController = segue.destinationViewController as! SubViewConroller 
    } 
} 

コールalmofireブロックからの真のセグエ名でセグエとboolVarを準備してグローバルブール変数を作成します。

+0

あなたの答えと時間をありがとう。私は質問があります:状況を考えてみましょう、私はボタンやsomethingsをParentViewControllerからSubViewControllerに移行するために押します。これは 'prepareForSegue()'を呼び出すことを意味します。もし、私がこのトランジションをトリガするときに 'boolVar'が' false'ならば、あなたの解決策は動作しますか(すべての点で!!!)? Alamofireがデータを取得する前にビューがフリーズするのですか、またはAlamofireがデータを取得するのと同じくらい時間がかかるようにボタンを押す必要がありますか? –

+0

この回答は理にかなっていません。 –

1

viewDidLoadでAlamofire Request Functionを呼び出す必要があります。完了ブロック(データを印刷した場所から)から応答を受け取ったときは、reload table dataに連絡してください。あなたが好きなテーブルビューをリロードすることができます

、これは:)

+0

まず、あなたの答えに感謝します。私は、 'reloadData()'を呼び出すたびに 'viewDidLoad()'が呼び出されるかどうかはわかりません。つまり、viewDidLoad()は、ビューがロードされるときに一度呼び出されます。おそらく 'viewWillAppear()'に 'reloadData()'をセットすることを意味しますか? –

+0

完了ハンドラでレスポンスを取得したときに、メソッドにリロードデータがありません。迅速に呼び出されているものはわからないが、レスポンスを受け取った後にのみ呼び出される補完ハンドラです。 – Lion

1

私が最初に気づいを助ける

self.tableView.reloadData() 

希望は、あなたが3つの非同期要求、ないものをやっているということです。あなたは補完ハンドラを使用することができますが、どちらのハンドラを使用できます2つの選択肢があると思います。

  1. ネットワーク通話をネストして、次の通話が開始されるようにネストします。このアプローチの欠点は、それらが順番に実行されることです。さらに追加する場合は、ネストを続行する必要があります。このようなアプローチは、2つのコールを行うだけであればOKですが、それを超えるとますます難しくなります。
  2. すべてのリモート呼び出しからすべてのデータがロードされるまで、セマフォを使用して待機します。完了ハンドラを使用してセマフォを通知します。このアプローチを使用する場合は、セマフォを使用するとスレッドがブロックされ、メインスレッドでそのスレッドを実行したくないため、バックグラウンドスレッドで実行する必要があります。

これら3つの呼び出しはすべて同時に発生します。 AlamoFireが完了していないにもかかわらず、関数は返されます。

self.dataRequest(self.availablePeriods401) 
    self.dataRequest(self.availablePeriods403) 
    self.dataRequest(self.availablePeriods405) 

これらは、AlamoFireが完了したかどうかに関係なく実行されます。

print(self.availablePeriods401.count) 
    print(self.availablePeriods403.count) 
    print(self.availablePeriods405.count)  

次のようになりますセマフォを使用:

override func viewWillAppear(animated: Bool) { 
    // maybe show a "Please Wait" dialog? 

    loadMyData() { 
     (success) in 
     // hide the "Please Wait" dialog. 

     // populate data on screen 

    } 
} 



func loadMyData(completion: MyCompletionHandler) { 

    // Do this in an operation queue so that we are not 
    // blocking the main thread. 

    let queue = NSOperationQueue() 
    queue.addOperationWithBlock { 
     let semaphore = dispatch_semaphore_create(0) 
     Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar1"]).responseJSON { 
      // This block fires after the results come back 

      // do something 

      dispatch_semaphore_signal(semaphore); 
     } 
     Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar2"]).responseJSON { 
      // This block fires after the results come back 

      // do something 

      dispatch_semaphore_signal(semaphore); 
     } 
     Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar3"]).responseJSON { 
      // This block fires after the results come back 

      // do something 

      dispatch_semaphore_signal(semaphore); 
     } 

     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 

     completion(true) 
    } 
} 

Apple Docs - Grand Central Dispatch

How to use semaphores

私はあなたのために持っている疑問は、あなたには、いくつかの場合、ビットではないやろうとしているものですすべてのWeb呼び出しが失敗しますか?

+0

あなたの答えをありがとう。問題が解決しました。 –

関連する問題