Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For Loop wait and delay - Swift 4

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.

like image 471
chivs688 Avatar asked Dec 11 '22 07:12

chivs688


2 Answers

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

like image 154
nikano Avatar answered Dec 29 '22 15:12

nikano


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) {}
like image 26
cse Avatar answered Dec 29 '22 16:12

cse