You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用URLSession.dataTask时变量重置的原因及解决方法

问题:URLSession.dataTask异步执行导致变量值未及时更新

Hey there, let's break down what's going on here and how to fix it. This isn't actually your variable getting "reset"—it's all about asynchronous execution timing.

Why this happens

URLSession.dataTask runs your network request on a background thread, which means it doesn't block the main thread while waiting for the response. When your code runs:

  1. You call checkToken() in viewDidLoad()
  2. checkToken() calls fetchToken(), which starts the data task and immediately returns (the network request is still running in the background)
  3. Your code moves right to print(iftokened)—at this point, the network request hasn't finished yet, so iftokened is still its initial value false
  4. Later, the network request completes, and the completion closure runs to set iftokened = true—but by then, your print statement has already executed, so you never see the updated value.

How to fix it

You need to wait until the asynchronous network request finishes before you act on the iftokened value. Here are a few solid approaches:

1. Handle the result directly in the completion closure (simplest solution)

Move your logic that depends on iftokened inside the completion handler, so it only runs after the network request completes:

override func viewDidLoad() {
    super.viewDidLoad()
    checkToken { [weak self] in
        // This code runs AFTER the network request finishes
        print(self?.iftokened ?? false)
        // Put any other logic that relies on iftokened here, like updating UI
    }
}

var iftokened = false

// Update checkToken to take its own completion handler
func checkToken(completion: @escaping () -> Void) {
    fetchToken { [weak self] (responseStatus) in
        self?.iftokened = (responseStatus == "200")
        // Call the completion to signal we're done
        completion()
    }
}

// Your existing fetchToken function stays mostly the same
let session: URLSession = {
    let config = URLSessionConfiguration.default
    return URLSession(configuration: config)
}()

func fetchToken(completion: @escaping (String) -> Void) {
    guard let url = URL(string: "http://www.google.com") else {
        completion("error")
        return
    }
    let request = URLRequest(url: url)
    let task = session.dataTask(with: request) { (data, response, error) in
        // Note: In real code, you should check the actual HTTP status code from the response, not just hardcode "200"
        if let httpResponse = response as? HTTPURLResponse {
            completion(String(httpResponse.statusCode))
        } else {
            completion("error")
        }
    }
    task.resume()
}

2. Use Async/Await (iOS 15+, cleaner syntax)

If your app targets iOS 15 or later, you can use Swift's async/await to make asynchronous code look more synchronous, avoiding nested closures:

override func viewDidLoad() {
    super.viewDidLoad()
    // Run async code in a Task
    Task {
        await checkToken()
        print(iftokened)
        // Other logic here
    }
}

var iftokened = false

func checkToken() async {
    let responseStatus = await fetchToken()
    iftokened = (responseStatus == "200")
}

// Convert fetchToken to an async function
func fetchToken() async -> String {
    guard let url = URL(string: "http://www.google.com") else {
        return "error"
    }
    let request = URLRequest(url: url)
    do {
        let (_, response) = try await session.data(for: request)
        if let httpResponse = response as? HTTPURLResponse {
            return String(httpResponse.statusCode)
        } else {
            return "error"
        }
    } catch {
        return "error"
    }
}

Important Note

Never block the main thread waiting for a network request (like using DispatchGroup.wait() on the main thread)—this will freeze your app's UI and lead to a bad user experience. Always use completion handlers or async/await to handle asynchronous work properly.

内容的提问来源于stack exchange,提问作者cRuiTe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:27:27