按顺序执行swift代码

时间:2015-09-06 23:07:11

标签: ios swift

在执行下一段代码(推送到故事板)之前,我需要完成“getUserInfo”。目前,当故事板推送执行时,“getUserInfo”仍在进行中。如何按顺序执行这些操作?我需要将这两个函数分开,所以将代码放在loginUser的完成处理程序中并不是一个好的解决方案。非常感谢那些比我更聪明的人:)

func loginUser() {
        PFUser.logInWithUsernameInBackground(txtEmailAddress.text, password:txtPassword.text) {
            (user: PFUser?, error: NSError?) -> Void in
            if user != nil {

                // Successful login.
                self.txtPassword.resignFirstResponder()
                self.txtEmailAddress.resignFirstResponder()

                getUserInfo()

                // Push to Main.storyboard.
                let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
                let viewController: AnyObject = storyboard.instantiateInitialViewController()
                self.presentViewController(viewController as! UIViewController, animated: true, completion: nil)

            } else {
                // The login failed. Display alert.
                self.displayAlert("Error", message: "Login incorrect")
            }
        }
}

func getUserInfo() {

    let currentUser = PFUser.currentUser()
    let userQuery = PFQuery(className: "_User")

    userQuery.whereKey("username", equalTo: PFUser.currentUser()!.username!)

    userQuery.findObjectsInBackgroundWithBlock({ (results:[AnyObject]?, error:NSError?) -> Void in
        if error == nil {
            for result in results! {
                userType = result["userType"] as! String

                if userType == "admin" {
                    user = "AdminSetting"
                } else {
                    user = "StandardSetting"
                }
            }
        }
    })

}

3 个答案:

答案 0 :(得分:0)

您要做的是使异步函数(具有完成处理程序的函数)同步,以便它立即返回。然而,这通常是一个坏主意,因为如果执行在主线程中停止,则用户无法执行任何操作,并且您的应用程序将停滞不前,直到代码再次继续。这可能需要几秒钟,具体取决于连接,这不是很好,您应该在异步任务上真正更新UI异步。通常没有充分理由做这样的事情,如果你有这样的话,你可以告诉我。

答案 1 :(得分:0)

您还可以在getUserInfo()中执行故事板代码,作为作为参数传入的块/闭包。这样,您可以确保在getUserInfo中的异步调用完成时执行

答案 2 :(得分:0)

Shadowman建议的是正确/最优雅的解决方案。

以下是一个例子:

func getUserInfo(completion: (results:[AnyObject]?, error:NSError?) -> Void) {

    let currentUser = PFUser.currentUser()
    let userQuery = PFQuery(className: "_User")

    userQuery.whereKey("username", equalTo: PFUser.currentUser()!.username!)

    userQuery.findObjectsInBackgroundWithBlock(completion)

}

通过这种方式,您可以在完成后从电话中取回实际结果,方便,嗯?

以下是您的称呼方式:

self.getUserInfo { (results, error) -> Void in

    // Here the results are already fetched, so proceed with your 
    // logic (show next controller or whatever...) 

    if error == nil {
        for result in results! {
            userType = result["userType"] as! String

            if userType == "admin" {
                user = "AdminSetting"
            } else {
                user = "StandardSetting"
            }
        }
    }

    // depending on whether this will still run in a background thread, you might have to dispatch this code to the main thread.
    // you can check whether this code block is called on the main thread
    // by checking if NSThread.isMainThread() returns true
    // if not, you will need to use this dispatch block!
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        // only call UI code in main thread! 
        // MOVE TO NEXT controller in here!
    })
}