[英]Alamofire completionHandler of responseJSON is not called
I have the following code to fetch the replies to a list of comments. 我有以下代码来获取对评论列表的回复。 (1 comment has many replies)
(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)
}
}
The complete handler of API.listReply
request is never called. 永远不会调用
API.listReply
请求的完整处理程序。 dispatch_group_enter(group)
is called once, and dispatch_group_leave(group) is never called. dispatch_group_enter(group)
被调用一次,并且从不调用dispatch_group_leave(group)。 The code gets stuck at dispatch_group_wait
. 代码卡在
dispatch_group_wait
。 What's strange is, even the UI is stuck, which is strange because the entire function is async. 奇怪的是,即使UI被卡住了,这也很奇怪,因为整个函数都是异步的。
I have encounter similar problem: 我遇到过类似的问题:
on Main UI thread, call: 在主UI线程上,调用:
dispatch_semaphore_wait(loginDoneSemaphore, DISPATCH_TIME_FOREVER)
and call http using Alamofire, internal also use your httpRequest.responseJSON
并使用Alamofire调用http,内部也使用您的
httpRequest.responseJSON
-> finally found code inside responseJSON completion handler never called - >最后发现代码里面的responseJSON完成处理程序从未调用过
-> cause find code after DISPATCH_TIME_FOREVER never called - >因为从未调用过DISPATCH_TIME_FOREVER后找到代码
-> finally find root cause is: Alamofire's responseJSON, default, if you not pass in the thread/queue, will run on Main UI thread - >最后找到根本原因是:Alamofire的responseJSON,默认情况下,如果没有传入线程/队列,将在主UI线程上运行
-> before call Alamofire, have inside Main UI thread, to use DISPATCH_TIME_FOREVER lock UI thread - >在调用Alamofire之前,有内部主UI线程,要使用DISPATCH_TIME_FOREVER锁定UI线程
-> so following Alamofire's responseJSON, which run also on Main UI thread, will never called - >所以遵循Alamofire的responseJSON,它也在主UI线程上运行,永远不会调用
-> my solution is: designate Alamofire do http response on another thread: - >我的解决方案是:指定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]
})
this maybe useful for you to refer. 这对你来说可能很有用。
-> maybe you can use my method: set another thread for Alamofire's responseJSON, to solve your problem. - >也许你可以使用我的方法:为Alamofire的responseJSON设置另一个线程来解决你的问题。
I'm not familiar with Alamofire internals, but it seems likely that it fulfills all your response completionBlocks on the same serial queue. 我不熟悉Alamofire内部,但它似乎可以在同一个串行队列中完成所有响应completionBlocks。 Your
dispatch_group_wait
is blocking other responses from finishing and calling their dispatch_group_leave
s. 您的
dispatch_group_wait
阻止其他响应完成并调用其dispatch_group_leave
。
You can solve this problem by using dispatch_group_notify
instead of dispatch_group_wait
, so rather than blocking the thread it will simply submit the block to a queue when necessary. 您可以使用
dispatch_group_notify
而不是dispatch_group_wait
来解决此问题,因此它不会阻塞线程,而是在必要时将块提交到队列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.