Ios 当我使用URLSession.dataTask完成某项作业时,我的var总是重置
当我请求web服务时,我想获取一些数据或完成一些工作。但当我使用Ios 当我使用URLSession.dataTask完成某项作业时,我的var总是重置,ios,swift,nsurlsession,Ios,Swift,Nsurlsession,当我请求web服务时,我想获取一些数据或完成一些工作。但当我使用URLSession.dataTask方法执行此操作时,我的var总是重置。为什么? 当我在func checkToken()中设置断点时,variftokend是true,因为responseStatus是“200”。但是当它返回到func viewDidLoad()时,变量iftokend被重置。当我打印它时,它是false。为什么?如何修复它 import UIKit import Foundation class View
URLSession.dataTask
方法执行此操作时,我的var总是重置。为什么?
当我在func checkToken()
中设置断点时,variftokend
是true
,因为responseStatus是“200”。但是当它返回到func viewDidLoad()
时,变量iftokend
被重置。当我打印它时,它是false
。为什么?如何修复它
import UIKit
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
checkToken()
print(iftokened)
}
var iftokened = false
func checkToken() {
fetchToken { [weak self] (responseStatus) in
if responseStatus == "200" {
self?.iftokened = true
} else {
self?.iftokened = false
}
}
}
let session: URLSession = {
let config = URLSessionConfiguration.default
return URLSession(configuration: config)
}()
func fetchToken(completion: @escaping (String) -> Void) {
let urlString = "http://www.google.com"
let url = URL(string: urlString)
let request = URLRequest(url: url!)
let task = session.dataTask(with: request) {
(data, response, error) in
completion("200")
}
task.resume()
}
}
您尝试的是异步的,因为会话在主线程以外的单独线程中运行,所以在调用url控件时,会传递到下一行,这是打印false的print语句,因为响应调用完成尚未更改变量
func checkToken() {
fetchToken { [weak self] (responseStatus) in
if responseStatus == "200" {
self?.iftokened = true
} else {
self?.iftokened = false
}
print(iftokened)
/// start using iftokened here
}
}
您需要使用semophore发出同步请求
func fetchToken(completion: @escaping (String) -> Void) {
let semaphore = DispatchSemaphore(value: 0)
let urlString = "http://www.google.com"
let url = URL(string: urlString)
let request = URLRequest(url: url!)
let task = self.session.dataTask(with: request) {
(data, response, error) in
completion("200")
semaphore.signal()
}
task.resume()
semaphore.wait(timeout: .distantFuture)
}
但您的代码还有其他问题:
- 当请求完成时,您应该从服务器获取响应状态,而不是在回调时使用completion(“200”)
if let response = response as? HTTPURLResponse { completion(response.statusCode) }
override func viewDidLoad() {
super.viewDidLoad()
checkToken(completion: { [weak self] response in
self?.iftokened = response
print(self?.iftokened ?? false)
})
}
var iftokened = false
func checkToken(completion: @escaping (Bool) -> Void){
fetchToken { (responseStatus) in
if responseStatus == "200" {
completion(true)
} else {
completion(false)
}
}
}
看看这里。这是个糟糕的主意。使用完成处理程序的全部要点是正确处理方法的异步性质。使用信号量和完成处理程序阻止返回没有任何意义。@cRuiTe没有什么需要修复的。代码的唯一问题是,
viewDidLoad
中的print语句在实际检索令牌之前很久就被调用了。将print语句放在checkToken
方法的正确位置,而不是viewDidLoad
。