2014-08-29 77 views
2

我在併發操作隊列中使用Alamofire(AF)在我的項目中運行網絡命令。有時AF的completionHandler不會開火,導致我的NSOperation掛起(等待完成消息,它永遠不會收到)。Alamofire和併發操作隊列

例如,我可以看到一個 「響應」 記錄,但沒有相應的 「看我」 從下面AF的dispatch_async登錄:

public func response(priority: Int = DISPATCH_QUEUE_PRIORITY_DEFAULT, queue: dispatch_queue_t? = nil, serializer: (NSURLRequest, NSHTTPURLResponse?, NSData?, NSError?) -> (AnyObject?, NSError?), completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self { 
NSLog("markse-response") 

    dispatch_async(self.delegate.queue, { 
NSLog("markse-see me") 
     dispatch_async(dispatch_get_global_queue(priority, 0), { 
      if var error = self.delegate.error { 
       dispatch_async(queue ?? dispatch_get_main_queue(), { 
        completionHandler(self.request, self.response, nil, error) 
       }) 
      } else { 
       let (responseObject: AnyObject?, serializationError: NSError?) = serializer(self.request, self.response, self.delegate.data, nil) 

       dispatch_async(queue ?? dispatch_get_main_queue(), { 
        completionHandler(self.request, self.response, responseObject, serializationError) 
       }) 
      } 
     }) 
    }) 

    return self 
} 

這是我的NSOperation(AsynchronousCommand是的NSOperation子類):

import Alamofire 

class SettingsListCommand: AsynchronousCommand { 

    override func execute() { 
     if cancelled { return } 

     let endpoint = "https://api.github.com/users/cog404/orgs" 

     DLogVerbose("AF request") 
     weak var weakSelf = self 
     Alamofire.request(.GET, 
      endpoint, 
      parameters:nil) 
      .responseJSON {(request, response, JSON, error) in 
       DLogVerbose("AF response") 
       if let strongSelf = weakSelf { 
        if strongSelf.cancelled { 
         strongSelf.finish() 
         return 
        } 
        DLogVerbose(JSON) 
        strongSelf.finish() 
       } 
     } 
    } 

} 

這隻會偶爾發生,這使得調試非常困難。

有沒有人對線程有很好的理解知道會出現什麼問題?

非常感謝您的任何建議。一個幫助說明問題的項目是here

回答

3

請求委託的調度隊列是串行的,這意味着它將只按照調度塊(FIFO)的順序一次處理一個塊。如果第二個日誌語句沒有被觸發,那是因爲之前的塊沒有完成。

+2

我的2美分:這個解決方案感覺過於複雜。如果你真的需要'NSOperation',只需使用塊操作和'dispatch_semaphore'。 – mattt 2014-09-24 23:33:24

+2

謝謝mattt。我花了一段時間來閱讀GCD,但現在這種行爲是有道理的。我會在閱讀更多內容之後考慮dispatch_semaphore方法(我長期在NSOperation世界生活過)。 – 2014-10-02 03:36:28