Swift Infinite Loops

Your app froze. Somewhere in your code, a loop is running forever, and now you need to understand why.
Written by

Chris C

Updated on

Apr 04 2026

Table of contents

    Overview

    An infinite loop is a loop that never reaches a stopping point. The condition stays true forever, or the code inside the loop never changes the value that would make the loop stop.

    In Swift, infinite loops can happen by accident, but they can also be intentional. The key is knowing which one you wrote. An accidental infinite loop can freeze an app, drain CPU, or make Xcode look like it has stopped responding.

    A Simple Infinite Loop

    The most direct infinite loop is while true. Since true never becomes false, the loop keeps running.

    while true {
        print("This keeps running")
    }

    This code has no exit path. Once it starts, it will keep printing until the program is stopped.

    Accidental Infinite Loops

    Most infinite loops are accidental. A common cause is forgetting to update the value used in the loop condition.

    var count = 0
    
    while count < 5 {
        print(count)
    }

    The condition checks whether count is less than five, but count never changes. The condition stays true forever.

    Here is the fixed version:

    var count = 0
    
    while count < 5 {
        print(count)
        count += 1
    }

    Using Break to Exit

    An intentional infinite loop needs a clear way to exit. The break statement immediately stops the nearest loop.

    var attempts = 0
    
    while true {
        attempts += 1
        print("Attempt \(attempts)")
    
        if attempts == 3 {
            break
        }
    }

    Even though the loop condition is always true, the break statement gives it an exit path.

    Repeat-While Infinite Loops

    repeat-while loops can also become infinite if the condition never becomes false.

    var isRunning = true
    
    repeat {
        print("Running")
    } while isRunning

    Because isRunning stays true, this loop never stops. To fix it, make sure something inside the loop can change the condition or use break when the work is done.

    Loops That Move the Wrong Direction

    Another easy mistake is updating a counter in the opposite direction from the condition.

    var number = 10
    
    while number > 0 {
        print(number)
        number += 1
    }

    This loop checks whether number is greater than zero, then makes number even larger. The condition will not become false.

    var number = 10
    
    while number > 0 {
        print(number)
        number -= 1
    }

    For Loops Are Usually Safer

    When you know exactly how many times a loop should run, a for-in loop is usually safer than a while loop because Swift controls the iteration for you.

    for number in 1...5 {
        print(number)
    }

    This loop has a clear range, so it naturally stops after the final value.

    Infinite Loops in App Code

    In app development, infinite loops are especially painful because they can block the main thread. If the main thread is stuck, the UI cannot update, respond to taps, or redraw.

    var isLoading = true
    
    while isLoading {
        // Waiting here blocks the thread.
    }

    In SwiftUI or UIKit, avoid waiting in a loop for state to change. Use async APIs, callbacks, tasks, timers, or published state updates instead.

    Using a Safety Limit

    When a loop depends on external data or a condition that might not change, a safety limit can prevent runaway behavior.

    var attempts = 0
    let maxAttempts = 5
    
    while attempts < maxAttempts {
        attempts += 1
        print("Checking attempt \(attempts)")
    }

    This pattern gives the loop a guaranteed upper bound, which makes the code easier to reason about.

    Debugging an Infinite Loop

    If you suspect a loop is running forever, inspect the condition and every variable involved in that condition.

    • Check whether the condition can ever become false.
    • Confirm that the loop body updates the value used by the condition.
    • Look for counters moving in the wrong direction.
    • Add temporary prints to see whether values are changing.
    • Use Xcode's debugger to pause execution and inspect the current line.

    Common Mistakes

    Forgetting to update the counter

    If your condition depends on a counter, the loop body usually needs to change that counter.

    Writing while true without an exit

    A while true loop should have an obvious break, return, or other exit path.

    Blocking the main thread

    Do not use a loop to wait for UI state or network results. Let Swift's asynchronous tools notify you when the work finishes.

    Quick Reference

    PatternWhat It Means
    while true { ... }Runs forever unless something exits the loop
    breakStops the nearest loop immediately
    while count < maxRuns while the condition remains true
    count += 1Moves a counter toward a stopping condition
    for item in itemsOften safer when looping through a known collection
    repeat { ... } while conditionRuns at least once, then repeats while the condition is true

    Summary

    • An infinite loop is a loop that never stops on its own.
    • Accidental infinite loops often happen when the loop condition never changes.
    • while true is only safe when there is a clear exit path.
    • break can stop a loop immediately.
    • Use for-in loops when you already know the collection or range.
    • Avoid blocking the main thread with loops that wait for state to change.
    • Safety limits can make condition-based loops more reliable.

    The habit to build is simple: every loop should have a believable stopping story. If you can point to exactly how and when the loop ends, you are far less likely to freeze your program by accident.