将值传递给闭包?

5

我希望在处理完最后一个项目后执行额外的逻辑,但终端显示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
            }
        })
    })
}

闭包可以捕获其外部作用域的变量,因此这段代码应该没问题。请提供您初始化“c”的位置。 - hris.to
如果“c”的值太高,这肯定会达到线程限制... - Danny Bravo
3个回答

7

当您的闭包被执行时,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
            }
        })
    })
}

6

您可以使用捕获列表[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

2
您需要声明一个变量(不是迭代变量)以获取正确的作用域,例如:
for var _i=0; _i<c; _i++ {
   let i = _i
   dispatch_async(...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接