当我使用URLSession.dataTask完成一些工作时,我的var总是重置

时间:2018-01-06 01:29:48

标签: ios swift nsurlsession

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

当我在func checkToken()中设置断点时,var iftokenedtrue,因为responseStatus是" 200"。但当它返回func viewDidLoad()时,var iftokened将被重置。当我打印它时,它是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()
    }
}

3 个答案:

答案 0 :(得分:0)

您正在尝试的是异步,因为会话在主线程以外的单独线程中运行,因此在调用url控件时会传递给下一行,即打印假的变量尚未更改的print语句响应呼叫完成

func checkToken() {
    fetchToken { [weak self] (responseStatus) in
        if responseStatus == "200" {
            self?.iftokened = true
        } else {
            self?.iftokened = false
        }

         print(iftokened)

         /// start using iftokened here 
    }
}

答案 1 :(得分:0)

尝试这种方式获取当前令牌状态

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)
       }
    }
}

答案 2 :(得分:-1)

您需要使用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)
    }

但您的代码也有其他问题:

  • 您应该在请求完成时从服务器获取响应状态,而不是在回调时使用完成(“200”)

    if let response = response as? HTTPURLResponse {               
     completion(response.statusCode)
    }