首页 > 解决方案 > 如何更正 Swift 5 中代码的执行顺序?

问题描述

函数中的代码以与预期不同的顺序执行。我想在 if 语句中更改登录布尔变量的状态,该函数在if 语句完成之前返回初始值

代码示例:

class ClassName {

    func loginRequest (name: String, pwd: String) -> Bool {

    var login:Bool
    //Initial value for login
    login = false



    let task = session.uploadTask(with: request, from: jsonData) { data, response, error in

        if let httpResponse = response as? HTTPURLResponse {
            print(httpResponse.statusCode)
            if (httpResponse.statusCode) == 200 {
                //Change the value of login if login is successful
                login = true
                if let data = data, let dataString = String(data: data, encoding: .utf8) {                    
                    do {

                        ...

                    } catch {print(error.localizedDescription)}

                }

            }

        } 

    }
        task.resume()
        //Problem return false in any case because return is completed before if statement
        return login   
    }
}

标签: swift5

解决方案


完成处理程序是你的朋友

您的代码运行的那一刻task.resume(),它将运行您的uploadTask,并且只有当该函数完成运行时,它才会运行您更改login变量的代码。

话虽如此:那段代码是异步运行的。这意味着您return login的代码行在运行之前不会等待您的网络请求返回。

您的代码实际上是按照应有的顺序运行的。但是我自己写了我的第一个网络电话,并且遇到了同样的问题。完成句柄是我修复它的方式


这是一个关于完成处理程序的非常好的教程,或者您可能将其称为回调

链接到完成处理程序教程


如果我能给你一点提示 - 你将不得不改变你的功能,让它看起来像这样:func loginRequest (name: String, pwd: String, completionHandler: @escaping (Bool) -> Void)

并将其替换login = truecompletionHandler(true)

无论你在哪里调用你的函数,它看起来都像这样:

loginRequest(name: String, pwd: String) {didLogIn in
    print("Logged In : \(didLogIn)")
}

最后一件事...您实际上已经在代码中使用了完成处理程序。 let task = session.uploadTask(with: request, from: jsonData) { data, response, error in ......但希望现在您能更好地理解一点,并在进行网络调用时使用完成处理程序方法。

祝你好运 !


推荐阅读