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

Swift多线程Dispatch Queue异步调用变量捕获异常问题

Swift中Dispatch Queue异步调用的参数捕获问题

为什么第一个代码会输出全10?

你的第一段代码里,queue.async传入的闭包捕获的是index变量的引用。因为循环执行速度远快于队列中闭包的执行速度,当闭包真正开始调用fun(index)时,index已经完成了所有循环迭代,值变成了10。所以所有闭包访问到的都是index的最终值,导致输出全是10。

代码示例:

import Foundation
let queue = DispatchQueue(label: "swiftlee.concurrent.queue", attributes: .concurrent)
let lock = NSLock()

func fun(_ idx: Int) {
    print(idx)
}


func calc() {
    var index = 0
    let dispatchGroup = DispatchGroup()
    while index < 10{
        dispatchGroup.enter()
        queue.async {
            fun(index)
            dispatchGroup.leave()
        }
        index += 1
    }
    dispatchGroup.wait()
}

calc()

为什么加局部变量x就能正常输出0-9?

在循环内新增let x = index后,每次循环迭代都会创建一个独立的x常量。Swift中,闭包对于值类型(比如Int)的捕获会直接复制其当前值,每个闭包捕获的是当前迭代中x的实例。虽然循环迭代结束后x的作用域就消失了,但闭包会保留捕获的值,直到自身执行完毕。因此每个闭包执行时,拿到的都是对应迭代时index的数值,最终能正确输出0到9。

代码示例:

import Foundation
let queue = DispatchQueue(label: "swiftlee.concurrent.queue", attributes: .concurrent)
let lock = NSLock()

func fun(_ idx: Int) {
    print(idx)
}


func calc() {
    var index = 0
    let dispatchGroup = DispatchGroup()
    while index < 10{
        dispatchGroup.enter()
        let x = index
        queue.async {
            fun(x)
            dispatchGroup.leave()
        }
        index += 1
    }
    dispatchGroup.wait()
}

calc()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:40:34