2016-07-05 1 views
1

だから私は、APIを介して返されることになっているトピックのリストを返しますが、レスポンスの閉鎖だけの機能が戻った後に実行される関数を持っています。どのように私はAlamofire要求に優先順位を付けていますか?

マイコード:

func getSectionsList (syllabus_ID: String) -> [String:String] { 

     var sectionDictionary = [String:String]() 
     var errorString: String! 
     let token = Keychain.value(forKey: "Auth_Token")! as String 
     manager.request(.GET, "\(BASE_URL)/syllabi/\(syllabus_ID)/sections?token=\(token)", encoding:.JSON).validate() 
      .responseJSON { response in 
       switch response.result { 
       case .Success: 

        let responseJSON = JSON(response.result.value!) 
        sectionDictionary = self.serializeJSON(responseJSON) 

        break 
       case .Failure(let error): 
        NSLog("Error result: \(error)") 
        errorString = "\(error)"    
        return 
       } 
      } 
     return sectionDictionary 
    } 

私はこのような完了ハンドラを使用してみました。だから今、それは返さない

var dictionary = [String:String]() 

    api.getSectionsList("1"){ 
     (dict, error)in 
     if dict.count != 0{ 
     dictionary = dict 
     } 
} 

func getSectionsList (syllabus_ID: String, completionHandler: ([String:String], String?)->()) { 

    var sectionDictionary = [String:String]() 
    var errorString: String! 
    let token = Keychain.value(forKey: "Auth_Token")! as String 
    manager.request(.GET, "\(BASE_URL)/syllabi/\(syllabus_ID)/sections?token=\(token)", encoding:.JSON).validate() 
     .responseJSON { response in 
      switch response.result { 
      case .Success: 

       let responseJSON = JSON(response.result.value!) 
       sectionDictionary = self.serializeJSON(responseJSON) 

       break 
      case .Failure(let error): 
       NSLog("Error result: \(error)") 
       errorString = "\(error)" 
       return 
      } 
      completionHandler(sectionDictionary, errorString) 
    } 
} 

そして、このようにそれを呼ばれます確かにもっと簡単な方法でなければならないような気がしますか?私がしたように達成することなく、私が望む値を返すだけの機能を持つことはできないのですか?

答えて

2

いや、あなたはクロージャ(完了ハンドラ)アプローチで頭の上に釘を打ってきました。

Alamofire機能.responseJSONは()あなたも閉鎖完了ハンドラパターンを介して非同期に返すために持っている非同期的にあなたに戻って来ています。

クロージャ内のリターンは、クロージャ自体の戻り値であり、クロージャ周囲の範囲ではありません。あなたの閉鎖が望んでいないこと

あなたはより良い私のポイントを説明するために、

([String:String], String?)->() 

AKA、としてあなたの閉鎖のタイプを定義した、これと同じであり、

[String:String], String?)->Void 

とにかく戻り値(従ってVoid)と私はコンパイラがあなたがそうしようとすると文句を言うと思います。

このを使用すると、asyncクロージャパターンを使用するほど便利になります。

あなたの関数からの戻り値が本当に必要な場合は、同期要求を使用してAlamofireで行うことができますが、実行サイクルをロックする理由は表示されません。あなたは比較的遅いタスクが完了するのを待つ。注意する

もう一つの事はあなたの閉鎖は、もともと上と呼ばなっているスレッドものです。私は間違っていなければ、.responseJSON()は常にバックグラウンドスレッドで返されると信じています。したがって、リクエストが返った後にUIを更新したい場合、メインスレッドになければ問題が発生します。簡単なテストは

if NSThread.mainThread() == NSThread.currentThread() { 
    print("ON MAIN THREAD") 
} else { 
    print("NOT ON MAIN THREAD") 
} 

を確認するために、あなたを教えてくれる、その上の主な私は他の一般的な間違いとハード1にあるスレッドについては、別のコメントを追加しました

dispatch_async(dispatch_get_main_queue(),{ 
    completionHandler(sectionDictionary, errorString) 
} 
+1

、GCDでこのような何かを行いますあなたが探しているかわからない場合は、診断;) – anders

+0

は何素晴らしい答え。ありがとうございました! – Glenncito

関連する問題