将值传递给闭包?

Pass value to closure?

我想在处理完最后一项后执行额外的逻辑,但终端显示 i 的值始终与 c 相同。知道如何传递循环变量吗?

let c = a.count
for var i=0; i<c; i++ {

   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {

        // ..

        dispatch_async(dispatch_get_main_queue(), {

            println("i \(i) c \(c)")
            if i == c-1 {

                // extra stuff would come here
            }
        })
    })
}

您需要声明一个变量(不是迭代变量)以获得正确的范围,例如

for var _i=0; _i<c; _i++ {
   let i = _i
   dispatch_async(...

当你的闭包被执行时,for 循环已经完成并且 i = c。您需要在 for 循环内添加一个辅助变量:

let c = a.count
for var i=0; i<c; i++ {
    let k = i
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {

        // ..

        dispatch_async(dispatch_get_main_queue(), {

            println("k \(k) c \(c)")
            if k == c-1 {

                // extra stuff would come here
            }
        })
    })
}

您可以使用 捕获列表 [i] 显式捕获 i 的值 在闭包中,那么你不需要将它复制到一个单独的变量。 示例:

let c = 5
for var i=0; i<c; i++ {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {
        [i] in   // <===== Capture list
        dispatch_async(dispatch_get_main_queue(), { 

            println("i \(i) c \(c)")
        })
    })
}

输出:

i 0 c 5
i 1 c 5
i 2 c 5
i 3 c 5
i 4 c 5