按值将 Int 传递给闭包

Pass Int by value to closure

我有这个代码:

for var i = 0; i < self.blockViews.count; i++ {
    UIView.animateWithDuration(0.2, animations: {
        // Some animation
        }, completion: {
            completion in
            // i is always blockViews.count as the for loop exits before completion closure is called
            if i == 0 {
                // Some completion handling
            }
    })
}

我正在尝试在闭包中使用 i;除了将它分配给 let,然后使用它(按值传递)之外,还有其他方法可以做到这一点吗?

for var i = 0; i < self.blockViews.count; i++ {
    let copyOfI = i
    UIView.animateWithDuration(0.2, animations: {
        // Some animation
        }, completion: {
            completion in
            if copyOfI == 0 {
                // This works
            }
    })
}

您要么必须使用 let 创建一个副本(就像您在问题中所做的那样),要么通过闭包的参数将其传递到闭包中。

鉴于您正在使用 UIView.animateWithDuration 闭包,最好的办法是将其分配给闭包内的 let 变量。

实际上有一种方法可以做到这一点,它被称为 捕获列表:您只需将要捕获的变量列为逗号分隔的列表并括在方括号中- 在你的情况下,它只是 [i]:

for var i = 0; i < self.blockViews.count; i++ {
    UIView.animateWithDuration(0.2, animations: {
        // Some animation
        }, completion: {
            [i] completion in
         // ^^^ capture list is here
            // i is always blockViews.count as the for loop exits before completion closure is called
            if i == 0 {
                // Some completion handling
            }
            println(i)
    })
}

参考:Closure Expression

旧答案

您可以将循环代码包含在闭包中并将索引作为闭包参数传​​递:

for var i = 0; i < self.blockViews.count; i++ {
    { (index) in
        UIView.animateWithDuration(0.2, animations: {
            // Some animation
            }, completion: {
                completion in
                // i is always blockViews.count as the for loop exits before completion closure is called
                if index == 0 {
                    // Some completion handling
                }
        })
    }(i)
}