[英]Alamofire completionHandler of responseJSON is not called
我有以下代碼來獲取對評論列表的回復。 (1條評論有很多回復)
static func fetchCommentsAndTheirReplies(articleId: String, failure: (()->Void)?, success: (comments: [[String: AnyObject]], replies: [[[String: AnyObject]]], userIds: Set<String>)->Void) {
var retComments = [[String: AnyObject]]()
var retReplies = [[[String: AnyObject]]]()
var retUserIds = Set<String>()
Alamofire.request(.GET, API.listComment, parameters: [API.articleId: articleId]).responseJSON {
response in
guard let comments = response.result.value as? [[String: AnyObject]] else {
failure?()
return
}
print(comments)
retComments = comments
let group = dispatch_group_create()
for (commentIndex, comment) in comments.enumerate() {
guard let id = comment["_id"] as? String else {continue}
let relevantUserIds = parseRelaventUserIdsFromEntity(comment)
for userId in relevantUserIds {
retUserIds.insert(userId)
}
retReplies.append([[String: AnyObject]]())
dispatch_group_enter(group)
Alamofire.request(.GET, API.listReply, parameters: [API.commentId: id]).responseJSON {
response in
if let replies = response.result.value as? [[String: AnyObject]] {
for (_, reply) in replies.enumerate() {
let relevantUserIds = parseRelaventUserIdsFromEntity(reply)
for userId in relevantUserIds {
retUserIds.insert(userId)
}
}
//TODO: need to capture commentIndex?
retReplies[commentIndex] = replies
}
dispatch_group_leave(group)
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
success(comments: retComments, replies: retReplies, userIds: retUserIds)
}
}
永遠不會調用API.listReply
請求的完整處理程序。 dispatch_group_enter(group)
被調用一次,並且從不調用dispatch_group_leave(group)。 代碼卡在dispatch_group_wait
。 奇怪的是,即使UI被卡住了,這也很奇怪,因為整個函數都是異步的。
我遇到過類似的問題:
在主UI線程上,調用:
dispatch_semaphore_wait(loginDoneSemaphore, DISPATCH_TIME_FOREVER)
並使用Alamofire調用http,內部也使用您的httpRequest.responseJSON
- >最后發現代碼里面的responseJSON完成處理程序從未調用過
- >因為從未調用過DISPATCH_TIME_FOREVER后找到代碼
- >最后找到根本原因是:Alamofire的responseJSON,默認情況下,如果沒有傳入線程/隊列,將在主UI線程上運行
- >在調用Alamofire之前,有內部主UI線程,要使用DISPATCH_TIME_FOREVER鎖定UI線程
- >所以遵循Alamofire的responseJSON,它也在主UI線程上運行,永遠不會調用
- >我的解決方案是:指定Alamofire在另一個線程上做http響應:
let BackgroundThread:dispatch_queue_t = dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)
func dispatchBackground_async(thingsTodo:()->()) {
dispatch_async(BackgroundThread, thingsTodo)
}
dispatchBackground_async({
httpRequest.responseJSON(queue: BackgroundThread, completionHandler: { response in
gLog.debug("request=\(response.request), response=\(response.response), statusCode=\(response.response?.statusCode), result=\(response.result)")
// [Debug] [com.apple.root.background-qos] [CrifanLibHttp.swift:21]
})
這對你來說可能很有用。
- >也許你可以使用我的方法:為Alamofire的responseJSON設置另一個線程來解決你的問題。
我不熟悉Alamofire內部,但它似乎可以在同一個串行隊列中完成所有響應completionBlocks。 您的dispatch_group_wait
阻止其他響應完成並調用其dispatch_group_leave
。
您可以使用dispatch_group_notify
而不是dispatch_group_wait
來解決此問題,因此它不會阻塞線程,而是在必要時將塊提交到隊列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.