2014-08-29 82 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