NSURLSession委托队列中的死锁

时间:2016-02-22 17:27:50

标签: ios multithreading swift nsurlsession alamofire

使用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

1 个答案:

答案 0 :(得分:1)

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

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