iOS Swift仅在应用程序的主线程错误上运行

use*_*668 3 ios uistoryboard swift

我是Swift的新手,我有一个登录页面,其中包含用户凭据,并检查其是否正确。我认为如果是正确的凭据,则以JSON返回响应,然后我尝试转到一个新的ViewController。当我尝试转到一个新的View Controller时遇到了此错误,我将其关闭了,所以我不知道为什么正在收到这个问题。这是我的代码

func LoginClosure(completion:@escaping (Bool) ->Void) {
    var check = 0
    let url:URL = URL(string:ConnectionString+"login")!

    if submitEmail == nil || submitPassword == nil {
        submitEmail = email.text!
        submitPassword = password.text!
    }

    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    let parameter = "Email=\(submitEmail!)&password=\(submitPassword!)"
    request.httpBody = parameter.data(using: String.Encoding.utf8)
    DispatchQueue.main.async {
        session.dataTask(with:request, completionHandler: { (data, response, error) in
            if error != nil {
                // print(error)
            } else {
                do {
                    let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]

                    if let Streams = parsedData?["Profile"] as? [AnyObject]  {
                        // check for misspelled words
                        for Stream in Streams {
                            if let rr = Stream["result"] as? Bool {
                                self.result = rr
                            } else {
                                self.result = true
                            }

                            if let id = Stream["id"] as? Int {
                                self.defaults.setValue(id, forKey: "my_id")
                                // Success
                                MYID = id
                                completion(true)
                                return
                            }
                        }

                        if check == 0 {
                            // Bad credentials
                            completion(false)
                        }
                    }
                } catch let error as NSError {
                    print(error)
                }
            }
        }).resume()
    }
}
Run Code Online (Sandbox Code Playgroud)

***由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“仅在主线程上运行!”

该行发生错误:

let next = self.storyboard?.instantiateViewController(withIdentifier: "AccountC") as! AccountC
self.present(next, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

Hit*_*esh 6

按照Apple标准,您只需要在主队列中执行UI活动。

只需在main queue下面调用您的闭包即可。

DispatchQueue.main.async {
    completion(true)
}
Run Code Online (Sandbox Code Playgroud)

您还可以仅在main queue下面进行UI更改。

DispatchQueue.main.async {
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AccountC") as! AccountC
    self.present(next, animated: true, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)

@rmaddy感谢您的宝贵建议。

  • 我认为最好将`DispatchQueue.main.async`的使用放到完成模块本身中。是完成模块中的代码,知道其任何代码是否应在主队列上运行。 (4认同)