swift5 - 如何更正 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
}
}
解决方案
完成处理程序是你的朋友
您的代码运行的那一刻task.resume()
,它将运行您的uploadTask
,并且只有当该函数完成运行时,它才会运行您更改login
变量的代码。
话虽如此:那段代码是异步运行的。这意味着您return login
的代码行在运行之前不会等待您的网络请求返回。
您的代码实际上是按照应有的顺序运行的。但是我自己写了我的第一个网络电话,并且遇到了同样的问题。完成句柄是我修复它的方式
这是一个关于完成处理程序的非常好的教程,或者您可能将其称为回调:
如果我能给你一点提示 - 你将不得不改变你的功能,让它看起来像这样: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
...
...但希望现在您能更好地理解一点,并在进行网络调用时使用完成处理程序方法。
祝你好运 !
推荐阅读
- linux - QThread isRunning 始终为真
- java - Comparator JAVA中带有比较方法的内部类
- mysql - 如何以非 localhost 用户身份登录 mysql
- python - 图像到 np 数组并保持顺序
- azure - 如何通过 Azure Basic P2S VPN 将静态 VPN 专用 ip 分配给客户端
- go - 如何在 Go 中将字节转换为布尔数组?
- html - ngbTypeahead - 悬停在菜单列表项上时显示标题
- julia - Julia Distributed - 为什么在评估表达式后没有在worker上定义变量?
- reactjs - React-Final-Form 延迟在 Field 中使用渲染道具获取输入
- image - 我可以将文件格式的容器映像(使用 docker save image >image.tar 创建)导入 Azure Container Register