Ios 未调用responseJSON的Alamofire completionHandler
我有以下代码来获取对评论列表的回复。(1条评论有很多回复)Ios 未调用responseJSON的Alamofire completionHandler,ios,swift,alamofire,Ios,Swift,Alamofire,我有以下代码来获取对评论列表的回复。(1条评论有很多回复) static func fetchcomments及其应用程序(articleId:String,failure:(()->Void)?,success:(注释:[[String:AnyObject]],回复:[[String:AnyObject]],userid:Set)->Void){ var retComments=[[String:AnyObject]]() var retrepries=[[[String:AnyObject]
static func fetchcomments及其应用程序(articleId:String,failure:(()->Void)?,success:(注释:[[String:AnyObject]],回复:[[String:AnyObject]],userid:Set)->Void){
var retComments=[[String:AnyObject]]()
var retrepries=[[[String:AnyObject]]]()
var retUserIds=Set()
请求(.GET,API.listcoment,参数:[API.articleId:articleId]).responseJSON{
回应
guard let comments=response.result.value as?[[String:AnyObject]]else{
失败?()
返回
}
打印(评论)
评论=评论
let group=dispatch\u group\u create()
对于comments.enumerate()中的(commentIndex,comment){
guard let id=comment[“_id”]作为字符串else{continue}
让relevantUserId=ParseRelaventUserIds=ParseRelaventUserFromEntity(注释)
对于相关userId中的userId{
retuserid.insert(userId)
}
追加([[String:AnyObject]]())
调度组输入(组)
请求(.GET,API.listReply,参数:[API.commentId:id])。响应JSON{
回应
如果让回复=response.result.value为?[[String:AnyObject]]{
在repress.enumerate()中为(u,reply){
让relevantUserIds=ParseRelaventUserIdFromEntity(回复)
对于相关userId中的userId{
retuserid.insert(userId)
}
}
//TODO:需要捕获注释索引吗?
回复[commentIndex]=回复
}
派遣组休假(组)
}
}
调度组等待(组、调度时间永远)
成功(注释:retComments,回复:retReplies,用户ID:RetUserID)
}
}
永远不会调用API.listReply
请求的完整处理程序<代码>调度组输入(组)只调用一次,从不调用调度组离开(组)。代码卡在调度组等待处
。
奇怪的是,甚至UI也被卡住了,这很奇怪,因为整个函数都是异步的 我不熟悉Alamofire的内部结构,但它似乎可以在同一个串行队列上完成所有响应完成块。您的
dispatch\u group\u wait
正在阻止其他响应完成并调用其dispatch\u group\u leave
s
您可以通过使用
dispatch\u group\u notify
而不是dispatch\u group\u wait
来解决此问题,因此它不会阻塞线程,而是在必要时将阻塞提交到队列。我遇到了类似的问题:
在主UI线程上,调用:
dispatch_semaphore_wait(loginDoneSemaphore, DISPATCH_TIME_FOREVER)
并使用Alamofire调用http,也可以使用您的httpRequest.responseJSON
->最终在responseJSON完成处理程序中找到了从未调用过的代码
->原因发送后查找代码\u时间\u永远不会调用
->最后找到的根本原因是:Alamofire的responseJSON,默认情况下,如果没有传入线程/队列,将在主UI线程上运行
->在调用Alamofire之前,在主UI线程内,使用DISPATCH\u TIME\u永久锁定UI线程
->所以,遵循同样在主UI线程上运行的Alamofire的responseJSON将永远不会被调用
->我的解决方案是:在另一个线程上指定Alamofire do 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是否使用内部串行队列?您可能无意中锁定了它。您应该在执行冻结时暂停执行,以查看它正在等待的位置。请始终停在这一行:
dispatch\u group\u wait(group,dispatch\u TIME\u everly)
但还有什么其他情况?该组中的某些块必须等待运行。我认为这是死锁问题。但不确定如何使用?尝试使用dispatch\u group\u notify而不是等待。
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]
})