Most developers default to a for
loop when they must loop through a collection or perform an operation several times. I find that the value of the while
loop is often overlooked. It has some advantages over Swift's for
loop in some scenarios. In this episode of Swift Fundamentals, you learn how to use a while
loop in Swift and, more important, when it is appropriate to use a while
loop over a for
loop. Let's get started.
What Is a While Loop?
Like a for
loop, a while
loop is a control flow statement for repeatedly executing a block of code. The difference with a for
loop is that the block of code is executed based on a boolean condition. You can also think of a while
loop as an if
statement that is executed multiple times until the statement of the if
clause evaluates to false
.
As I said, the block of code you pass to the while
loop is only executed if a condition is met. Only if the condition evaluates to true
, the code block is executed. What sets a while
loop apart from a for
loop is that the number of repetitions is undefined. In other words, the condition defines when the while
loop stops executing the statements in its body. Let's look at an example to better understand what I just explained.
Fire up a playground in Xcode if you want to follow along. Choose the Blank template from the iOS > Playground section.
In this example, the code block we pass to the while
loop is executed ten times. We declare a variable i
of type Int
and assign it a value of 10
. The statements of the while
loop are only executed if the condition evaluates to true
, that is, if the value stored in i
is less than or equal to 10
.
import Foundation
var i = 1
while i <= 10 {
print(i)
i += 1
}
Because we increment the value of i
with 1
every time the code block is executed, the while
loop stops executing the statements in its body after 10
iterations.
When to Use a While Loop?
While we could replace the while
loop in the example with a for
loop, that isn't always possible or recommended. A while
loop is a good choice if you don't know how often the code block is executed. In the example we increment the value of i
with 1
every time the code block of the while
loop is executed, but the logic is typically more complex.
You need to remember that a while
loop is typically more appropriate than a for
loop, and even necessary when you don't know in advance how many times you need to loop through a block of code. Remember what I said earlier. A while
loop is nothing more than an if
statement repeated several times until the condition of the if
statement evaluates to false
.
do {
let reader = try FileReader(url: fileURL)
defer {
reader?.close()
}
while let line = reader?.nextLine() {
print(line)
}
} catch {
print("Unable to Read File at \(fileURL), \(error)")
}
In this example, we use the FileReader
class to read the lines of a file one by one. Let's focus on the while
loop. In the condition of while
loop, we ask the file reader for the next line of the file. The return type of the nextLine
is String?
so we use optional binding to unwrap the next line. This is another excellent example of when a while
loop is a great fit. The while
loop stops executing the statements in its body when the nextLine()
method returns nil
.
Infinite Loops
Let's revisit the first example. What happens if you forget to increment i
in the code block of the while
loop? You end up with an infinite loop, the nightmare of every developer. The application enters an infinite loop if the condition of the while
loop never evaluates to false
.
From the user's perspective, the application becomes unresponsive if this occurs on the main thread. After a while, pun intended, the system may terminate your application. Entering an infinite loop is the most important risk of a while
loop. Be careful.
Don't Use a While Loop If ...
The while
loop isn't as common as the for
loop and that is a good thing. A for
loop is often easier to implement and understand, and the risk of entering an infinite loop is much. smaller. If you know how many times a block of code needs to be executed, then a for
loop is the better choice. Optimize for readability and ease of use.