如何在异步功能完成后调用函数?

时间:2016-01-06 18:40:11

标签: ios swift

我有一个在后台异步运行的函数Admin

有没有办法在调用代码之后确保函数完成?

(我使用flag检查异步操作是否成功。如果标志为0,则用户不是管理员,应该转到NormalLogin()

@IBAction func LoginAction(sender: UIButton) {
  Admin()

  if(bool.flag == 0) {
    NormalLogin()
  }
}




func Admin() {
  let userName1 = UserName.text
  let userPassword = Password.text
  let findTimeLineData2:PFQuery = PFQuery(className: "Admins")
  findTimeLineData2.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in

    if !(error != nil){
      for object in objects as! [PFObject] {
        let userName2 = object.objectForKey("AdminUserName") as! String
        let userPassword2 = object.objectForKey("AdminPassword") as! String

        if(userName1 == userName2 && userPassword == userPassword2) {
          //hes an admin
          bool.flag = 1

          self.performSegueWithIdentifier("AdminPage", sender: self)

          self.UserName.text = ""
          self.Password.text = ""
          break;
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

您需要查看完成处理程序和异步编程。这是一个可以复制到游乐场的异步函数示例:

定义功能

注意"完成"参数实际上是一个类型为(Bool)->()的函数。这意味着该函数采用布尔值并且不返回任何内容。

func getBoolValue(number : Int, completion: (result: Bool)->()) {
    if number > 5 {
        // when your completion function is called you pass in your boolean
        completion(result: true)
    } else {
        completion(result: false)
    }
}

调用函数

此处getBoolValue首先运行,当调用完成处理程序时(上面的代码),您的闭包运行时会传递上面传递的结果。

getBoolValue(8) { (result) -> () in
    // do stuff with the result
    print(result)
}

应用概念

您可以通过执行以下操作将此概念应用于您的代码:

@IBAction func LoginAction(sender: UIButton) {
    // admin() calls your code, when it hits your completion handler the 
    // closure {} runs w/ "result" being populated with either true or false
    Admin() { (result) in
        print("completion result: \(result)") //<--- add this
        if result == false {
            NormalLogin()
        } else {
            // I would recommend managing this here.
            self.performSegueWithIdentifier("AdminPage", sender: self)
        }
    }
}

// in your method, you pass a `(Bool)->()` function in as a parameter 
func Admin(completion: (result: Bool)->()) {
  let userName1 = UserName.text
  let userPassword = Password.text
  let findTimeLineData2:PFQuery = PFQuery(className: "Admins")
  findTimeLineData2.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in

    if !(error != nil){
      for object in objects as! [PFObject] {
        let userName2 = object.objectForKey("AdminUserName") as! String
        let userPassword2 = object.objectForKey("AdminPassword") as! String

        if(userName1 == userName2 && userPassword == userPassword2) {
          // you want to move this to your calling function
          //self.performSegueWithIdentifier("AdminPage", sender: self)

          self.UserName.text = ""
          self.Password.text = ""
          // when your completion handler is hit, your operation is complete
          // and you are returned to your calling closure
          completion(result: true) // returns true
        } else {
          completion(result: false) // returns false
        }
      }
    }
  }
}

当然,我无法编译您的代码来测试它,但我认为这样可以正常工作。