For Loop wait and delay - Swift 4

10,074

Solution 1

As I understand, what you tried to do is the following:

for _ in 0...3 {
   for player in 0...15 {
     // CODE ADDING MOVEMENTS TO QUEUE
   }

   updateBoardArray()
   printBoard()

   DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {}
}

This will NOT work since what you are doing is add a task (that will do nothing) to the main queue that will get trigged after 1 second, and after adding it, the code continues with the for, without waiting.

Solution

What you could do is simply use sleep(1), but bear in mind that this will freeze the main thread (if you are executing this in the main thread).

To avoid freezing the app you could do is:

  DispatchQueue.global(qos: .default).async {
       for _ in 0...3 {
            for player in 0...15 {
                // CODE ADDING MOVEMENTS TO QUEUE
            }

            DispatchQueue.main.async {
                updateBoardArray()
                printBoard()
            }

            sleep(1)

            }
        } 
   }

Just keep in mind that any UI action you do, must be done in the main thread

Solution 2

asyncAfter() function takes DispatchTime. DispatchTime is in nanosecond. Following is prototype:

func asyncAfter(deadline: DispatchTime, execute: DispatchWorkItem)

Following is extract of docs from Apple Developer webpage:

DispatchTime represents a point in time relative to the default clock with nanosecond precision. On Apple platforms, the default clock is based on the Mach absolute time unit

To solve the problem, use:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1000) {}
Share:
10,074
chivs688
Author by

chivs688

Updated on June 16, 2022

Comments

  • chivs688
    chivs688 almost 2 years

    I have a nested for loop, and am trying to make it so that the outer loop will only continue once the inner loop and its code is completed, and also add a 1 second delay before performing the next loop.

        for _ in 0...3 {
            for player in 0...15 {
                // CODE ADDING MOVEMENTS TO QUEUE
            }
            updateBoardArray()
            printBoard()
    
            // NEED TO WAIT HERE FOR 1 SEC
        }
    

    So I wan't the 0...3 For loop to progress only once the inner loop and update and print functions have completed their cycle, and also a 1 second wait time.

    At the moment it all happens at once and then just prints all 4 boards instantly, even when I put that 1 second wait in using DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {}.

    Have tried other answers to similar questions but can't seem to get it to work.

  • Rob Napier
    Rob Napier about 6 years
    It's clearer now to use .now() + .seconds(1). Otherwise it's easy to get confused about what "1000" means.
  • Alex McPherson
    Alex McPherson over 3 years
    Awesome stuff. Exactly what I needed too.