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
相关产品推荐
相关产品推荐

