如何更正Swift5中代码的执行顺序?

How to correct the order of execution of code in Swift 5?

函数中的代码 的执行顺序 与预期不同。我想在 if 语句 中更改 login 布尔变量 的状态,但是函数 returns if 语句完成 之前的初始值

Code sample:

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   
    }
}

Completion Handlers is your friend

当你的代码 运行s task.resume() 时,它将 运行 你的 uploadTask 并且只有当该功能完成时 运行 它将 运行 您更改 login 变量的代码。

With 也就是说:那段代码是 运行ning 异步的。这意味着您的 return login 行代码不会等待您的网络请求在 运行 之前返回。

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


这里有一个关于 Completion Handlers or you might know it as Callbacks 的非常好的教程:

Link To Completion Handlers Tutorial


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

并将此 login = true 替换为 completionHandler(true)

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

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

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

祝你好运!