【问题标题】:UIKeyboardTaskQueue may only be called from the main threadUIKeyboardTaskQueue 只能从主线程调用
【发布时间】:2016-09-18 16:07:17
【问题描述】:

我在尝试创建一个自动创建 POST 请求、发送它们、获取响应并处理它们然后显示 UIAlertView 以告诉用户是哪个问题的函数时遇到问题。

这是我的代码:

let task = session.dataTaskWithRequest(request, completionHandler:{ (data, response, error) -> Void in

    dispatch_async(dispatch_get_main_queue(),{
        var alert = UIAlertController(title: "Chargement", message: "Envoi des informations...", preferredStyle: UIAlertControllerStyle.Alert)
        viewController.presentViewController(alert, animated: true, completion: nil)


        answer = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        print(answer)
    var complete = false
    alert.dismissViewControllerAnimated(true, completion: { () -> Void in
        complete = true
    })

    while(!complete)
    {

    }
    var textmsg: String
    if(answer == "#400")
    {
        textmsg = "Il manque une information !"
    }
    else if(answer == "#50")
    {
        textmsg = "Le compte fourni ne correspond pas."
    }
    else if(answer == "#100")
    {
        textmsg = "Impossible d'identifier l'application."
    }
    else if(answer == "#1")
    {
        textmsg = "Transfert terminé avec succès !"
    }
    else {
        textmsg = "Echec du transfert."
    }
    let alertComplete = UIAlertController(title: "Chargement", message: textmsg, preferredStyle: UIAlertControllerStyle.Alert)
    alertComplete.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
    viewController.presentViewController(alertComplete, animated: true, completion: nil)
    })
})

task.resume();

错误代码如下:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'

当我的请求返回错误的响应(#400、#50、#100)时,代码可以工作并显示 UIAlertView,但如果响应良好,它会给我上面的错误代码。

【问题讨论】:

    标签: ios swift swift2.3


    【解决方案1】:

    您应该在主线程上调用 UIAlertController,因为您正在处理 ui。

    斯威夫特 2.X

    dispatch_async(dispatch_get_main_queue(),{ 
                   var alert = UIAlertController(title: "Chargement", message: "Envoi des informations...", preferredStyle: UIAlertControllerStyle.Alert)
                    viewController.presentViewController(alert, animated: true, completion: nil)
    
                    answer = NSString(data: data!, encoding: NSUTF8StringEncoding)!
                    print(answer)
                 var complete = false
        alert.dismissViewControllerAnimated(true, completion: { () -> Void in
            complete = true
        })
        while(!complete)
        {
    
        }
    }
    

    斯威夫特 4.2

    DispatchQueue.main.async {
        var alert = UIAlertController(title: "Chargement", message: "Envoi des informations...", preferredStyle: UIAlertControllerStyle.Alert)
        viewController.presentViewController(alert, animated: true, completion: nil)
    
        let answer = String(data: data!, encoding: .utf8)!
        print(answer)
        var complete = false
        alert.dismissViewControllerAnimated(true, completion: { () -> Void in
            complete = true
        })
        while(!complete)
        {
    
        }
    }
    

    【讨论】:

    • 但是当我的服务器返回 #400、#50 或 #100 时 UI 可以工作,所以我猜它来自成功声明:/
    • 当您收到响应时,您正在另一个线程中处理 ui 元素,但您应该只在主线程中使用 ui。
    • 尝试删除 While(!complete) 并将您要执行的所有代码放入dismissViewControllerAnimated 的完成中,并在完成中使用dispatch_async(dispatch_get_main_queue() 来调用该代码。跨度>
    【解决方案2】:

    对于 swift 3.x 和 4.x

    DispatchQueue.main.async(execute: {
    // work Needs to be done
     })
    

    【讨论】:

    • 谢谢它对我有用,但有人可以解释一下为什么它可以解决问题吗?
    • 您正在使用一个后台线程,该线程将请求调用到您正在调用的 ws,而 iOS 只允许您更改主线程上的 UI 组件,因此调用它:DispatchQueue.main。异步,您将返回主线程 (UI) 以更改/处理 UI 更改
    猜你喜欢
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多