如何将代码执行移至主队列

How to move code execution to the main qeue

我想提一下,我已经看到很多类似的问题并尝试了那里的代码,但我的代码仍然异步运行(我仅在第二次单击登录按钮后才移动到另一个 ViewController .这就是为什么我非常感谢您指出我的代码中的问题,而不是将我引用给其他人。

我有一个方法可以将登录数据发送到服务器

import UIKit
var IS_LOGGED_IN = Bool()

class LoginDataSender: UIView {
    func sendLogInData() {
        let myUrl = NSURL(string: "https://somewebsite")
        let request = NSMutableURLRequest(URL: myUrl!)
        request.HTTPMethod = "POST"
        let postString = "username=NAME&password=PASS"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

        NSURLSession.sharedSession().dataTaskWithRequest(request) {
            (data, respoonse, error) in

            if error != nil
            {
                print("error=\(error)")
                return
            }

            dispatch_async(dispatch_get_main_queue(), {
                do {
                    let myJson = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSDictionary

                    IS_LOGGED_IN = myJson.valueForKey("status") as! Bool
                    print(IS_LOGGED_IN)

                } catch {
                    print(error)
                }
            })

        }.resume()
    }
}

我从 ViewController

调用这个方法
import UIKit

class LoginViewController: UIViewController {

    let logInDataSender = LoginDataSender()

    @IBAction func pressLoginButton(sender: AnyObject) {

       logInDataSender.sendLogInData()

        if IS_LOGGED_IN {
            performSegueWithIdentifier("LogInSegue", sender: self)

        } 
}

如您所见,我将结果结果存储在一个全局变量 IS_LOGGED_IN 中,并基于此我是否执行 segue。 现在我只是硬编码 login/password 用于测试目的。

第一次点击登录按钮时,我应该把dispatch_async放在哪里才能使用IS_LOGGED_IN值?非常感谢!

练习使用完成处理程序而不是全局变量。在这种情况下,您可以使用 like:

func sendLogInData(completionhandler: (Bool)->()) {
    //.......
    dispatch_async(dispatch_get_main_queue(), {
            do {
                let myJson = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSDictionary
                completionhandler(myJson.valueForKey("status") as! Bool)
            } catch {
                completionhandler(false)
                print(error)
            }
        })
    //.....
}

然后在你的LoginViewController操作方法中:

 @IBAction func pressLoginButton(sender: AnyObject) {
    logInDataSender.sendLogInData { (loggedIn) in
    if loggedIn == true {
       //Logged In
       performSegueWithIdentifier("LogInSegue", sender: self)
    }else{
       //Not logged in
    }
  }
}