Alamofire 和并发操作队列

Posted

技术标签:

【中文标题】Alamofire 和并发操作队列【英文标题】:Alamofire and Concurrent Operation Queues 【发布时间】:2014-08-29 14:32:55 【问题描述】:

我在并发操作队列中使用Alamofire (AF) 在我的项目中运行网络命令。有时 AF 的 completionHandler 不会触发,让我的 NSOperation 挂起(等待它永远不会收到的完成消息)。

例如。我会看到“响应”日志,但下面没有来自 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。

【问题讨论】:

【参考方案1】:

请求委托的调度队列是串行的,这意味着它一次只会处理一个块,按照块被调度的顺序 (FIFO)。如果第二个日志语句没有触发,那是因为前一个块还没有完成。

【讨论】:

我的 2 美分:这个解决方案感觉过于复杂。如果您真的需要NSOperation,只需使用块操作和dispatch_semaphore 谢谢马特。我花了一些时间来阅读 GCD,但现在这种行为是有道理的。在阅读更多内容后我会考虑 dispatch_semaphore 方法(我在 NSOperation 世界中生活了很长时间)。

以上是关于Alamofire 和并发操作队列的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire RequestRetrier,在主操作队列上调用完成块可以吗?

使用 alamofire 的顺序上传/串行队列

有没有办法配置 Alamofire 不将结果分派到主队列?

正确使用 Alamofire 队列

Alamofire如何维护请求顺序?

Alamofire - 有没有办法设置自定义默认队列来处理所有请求回调