函数中的代码以与预期不同的顺序执行。我想在 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
}
}
答案 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
...
...但是希望现在您能更好地理解,并且在进行网络调用时将使用完成处理程序方法。
祝你好运!