Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass value to closure?

Tags:

ios

swift

block

I want to do extra logic after last item was processed, but terminal show that i has always the same value as c. Any idea how to pass the loop variable in?

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
            }
        })
    })
}
like image 747
János Avatar asked Jul 22 '15 14:07

János


2 Answers

By the time your closure is executed, the for loop has already finished and i = c. You need an auxiliary variable inside the for loop:

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
            }
        })
    })
}
like image 134
Glorfindel Avatar answered Sep 28 '22 16:09

Glorfindel


You can capture the value of i explicitly with a capture list [i] in the closure, then you don't need to copy it to a separate variable. Example:

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)")
        })
    })
}

Output:

i 0 c 5
i 1 c 5
i 2 c 5
i 3 c 5
i 4 c 5
like image 23
Martin R Avatar answered Sep 28 '22 15:09

Martin R