Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当我使用URLSession.dataTask完成某项作业时,我的var总是重置_Ios_Swift_Nsurlsession - Fatal编程技术网

Ios 当我使用URLSession.dataTask完成某项作业时,我的var总是重置

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

当我请求web服务时,我想获取一些数据或完成一些工作。但当我使用
URLSession.dataTask
方法执行此操作时,我的var总是重置。为什么?

当我在
func checkToken()
中设置断点时,var
iftokend
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