【问题标题】:Deadlock inside NSURLSession delegate queueNSURLSession 委托队列中的死锁
【发布时间】:2016-06-04 06:08:40
【问题描述】:

在使用 Alamofire 时,我在 NSUrlSession 委托队列中的一项操作中遇到了死锁。

当我同时进行至少一次下载和一次上传时会发生这种情况(所有请求都通过默认的 Alamofire 管理器完成)。从多个线程这样做有什么问题吗? (在 NSUrlSession 或 Alamofire 中)

它似乎卡在 NSURLSession 委托队列中的一项操作中的 __psynch_mutexwait 上,并且它完全关闭了应用程序通过 Alamofire 发出网络请求的能力(因为永远不会调用委托)。

正如我所说,下载和上传在 2 个不同的队列上同时调用(其中一个通常在主线程上调用)

上传示例:

        Alamofire.upload(.POST, uploadURL,
        multipartFormData: { multipartFormData in
                multipartFormData.appendBodyPart(data: x.dataUsingEncoding(NSUTF8StringEncoding)!, name: "X")
                multipartFormData.appendBodyPart(data: fileData, name: "file", fileName: "Y", mimeType: "application/octet-stream")
            }
        },
        encodingCompletion: { encodingResult in
            switch encodingResult {
            case .Success(let upload, _, _):
                upload.response { (request, response, data, error) -> Void in
                    if let error = error {
                        callback("Failure", "\(error)")
                    } else {
                        callback("SUCCESS", nil)
                    }
                }
            case .Failure(let encodingError):
                callback(nil, "Failed due to \(encodingError)")
            }
        }
    )

下载示例:

    Alamofire.download(.GET, downloadUrl, parameters: ["a": "a", "b": "b"], destination:
        {
            tempURL, response in
            return path
    }).response {
        (request, response, _, error) in
        let data = NSData(contentsOfURL: path)
        doSomeStuffWithDownloadedData(data)
        // make another request after download completed
        Alamofire.request(.GET, requestUrl, parameters: ["c":"c", "d":"d"]).response {
            request, response, data, error in
            if let e = error {
                log.error("request failed, \(e)")
            }
        }
    }

stack trace

【问题讨论】:

  • 您有示例代码和/或我们可以查看的一些输出或日志吗?
  • 添加了代码示例和堆栈跟踪

标签: ios multithreading swift nsurlsession alamofire


【解决方案1】:

在评论了我的大部分代码后,我隔离了导致问题的代码,它与 alamofire 或 NSURLSession 完全无关。

我在自己的代码中调用了一个数组(对象)上的objc_sync_enter,它总是在同一个数组上调用一个匹配的objc_sync_exit。在将此调用更改为self 而不是此数组后, NSBlockOperation 内部的死锁就消失了。这可能与数组不是对象而是结构这一事实有关。因此,如果您在代码中遇到非常奇怪的死锁,我建议您在尝试其他任何操作之前,请确保您没有在结构上调用 objc_sync_enter

【讨论】:

  • 您能否发布有关阵列死锁的代码。我使用 AFNetworking 遇到了同样的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 1970-01-01
相关资源
最近更新 更多