如何使用回调在 Swift 中进行异步调用,以便 main UI 不挂起?

How to use callbacks to make Asynchronous calls in Swift so that main UI does not Hang?

我正在尝试进行异步调用(对 Parse),在调用期间我希望我的 Main UI 挂起。

下面是我试图调用 ViewController 的函数。该函数下方是我在 ViewController.

中使用的代码

sleep(4) 行中,ViewController LoginVC 的主 UI 确实卡住了。我没有正确使用异步调用的回调吗?

class Utils {

func logIntoWebService(uname: String, pwd: String, completion: ((result:Bool?) -> Void)!) {

    PFUser.logInWithUsernameInBackground(uname, password:pwd) {
        (user, error) -> Void in

        if error == nil {
            if user != nil {
                // Yes, User Exists

                //UI IS STUCK DURING THIS SLEEP(10)
                sleep(10)

                completion(result: true)

            } else {
                completion(result: false)
            }
        } else {

            completion(result: false)

        }

    }
}

}

我正在从 ViewController 调用上述函数。以下是我的 ViewController

打来的电话
class LoginVC: UIViewController {

var mUtils: Utils = Utils()

mUtils.loggedInStatus({ (result) -> Void in
        println("Response from logInToParse = " + String(stringInterpolationSegment: result))

    })

}

您混淆了后台线程和完成处理程序。

logInWithUsernameInBackground 是一个异步函数,运行s 在后台,但是 运行s 在完成处理程序中的所有代码 运行s 回到主线程:

 completion: ((result:Bool?) -> Void)!) {//The code here runs in the main thread}

所以基本上从您的应用程序开始与 Parse.com 通信开始,直到结果返回,该代码在后台线程中 运行ning 是异步的,当它完成并且您的应用程序收到它 运行 在主线程的完成块中返回的响应。

现在假设您真的想 运行 在完成块的后台编写一些代码,而不是使用类似的代码:

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
    println("Now this code will run in the background thread")
})

所有新的服务质量 类 是:

QOS_CLASS_USER_INTERACTIVE
QOS_CLASS_USER_INITIATED
QOS_CLASS_UTILITY
QOS_CLASS_BACKGROUND

或者您的情况:

PFUser.logInWithUsernameInBackground(uname, password:pwd) {
    (user, error) -> Void in
    if error == nil {
        if user != nil {
            // Yes, User Exists

            let qualityOfServiceClass = QOS_CLASS_BACKGROUND
            let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
            dispatch_async(backgroundQueue, {
                sleep(10)
            })
            completion(result: true)

        } else {
            completion(result: false)
        }
    } else {

        completion(result: false)
    }
}

有关详细信息,请参阅 Apple documentation