如何在Swift 5中更正代码的执行顺序?

时间:2019-09-20 10:03:26

标签: swift5

函数中的代码以与预期不同的顺序执行。我想在 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   
    }
}

1 个答案:

答案 0 :(得分:2)

  

Completion Handlers是你的朋友

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

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

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


这是一个关于Completion Handlers的非常不错的教程,或者您可能以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 ... ...但是希望现在您能更好地理解,并且在进行网络调用时将使用完成处理程序方法。

祝你好运!