У меня есть следующая функция, которая не ведет себя так, как я ожидал.Проблема с Grand Central Dispatch с использованием Swift
func dispatchTrouble(startValue:Float, endValue:Float, duration:Float)
{
//100 increment steps per second
let incrementSteps = duration * 100
for(var step = 0.0 as Float; step < incrementSteps; step++)
{
var delayInSeconds = step * (duration/incrementSteps)
let answer = Float(NSEC_PER_SEC) * delayInSeconds
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(answer))
println(step)
//Using GCD to perform this on the main thread.
dispatch_after(popTime, dispatch_get_main_queue()){
println(step)
let fraction = step/incrementSteps
let incrementedValue = startValue + (endValue - startValue) * fraction
println(incrementedValue)
}
}
}
Я ожидал, что заявление Println (incrementedValue), чтобы отобразить значение, которое увеличивается с startValue до endValue и закончить в число секунд, прошедших в срок.
Однако поведение, которое я получаю, заключается в том, что код в dispatch_after закрывает только окончательное значение, он никогда не печатает приращения.
Задержка происходит, как ожидалось, но значения рассчитываются так, как если бы цикл for уже был завершен. Первый println (шаг) показывает шаг приращения, но второй показывает только окончательное значение.
У меня явно есть непонимание того, как это должно работать. Я ожидал, что код в закрытии будет содержать значения, существовавшие в момент вызова метода dispatch_after, но он действует так, как будто он использует то, что значение находится во время выполнения на самом деле.
Как я могу захватить значения на каждой итерации цикла for и выполнить код в закрытии, используя это?
Большое спасибо! Это убило меня. – Scooter
Мое предположение заключается в том, что 'step' получает коробку - в предположении, потому что' println() 'в лямбда принимает объект. Помните, что компилятор не знает, что 'println()' не изменяет 'step'. Я предполагаю, что альтернатива взятия неизменяемой копии по значению при захвате создаст не менее удивительные результаты ... – marko
@marko компилятор должен знать, что, учитывая, что структура имеет семантику copy-on-assign, 'println' никогда не может изменять шаг – Juan