Conditional Breakpoints in Xcode - Debug Specific States Faster

September 5, 2026

When debugging a collection of values, a breakpoint can quickly become noisy.

You may only care about one specific item, for example, the object whose id is 42. But if your breakpoint pauses every time the surrounding code executes, you end up repeatedly continuing execution until the interesting state appears.

Conditional breakpoints let Xcode do that filtering for you.

Instead of stopping every time a line executes, you can tell Xcode to pause only when an expression evaluates to true.


The problem with ordinary breakpoints

Consider a list of products:

struct Product {
    let id: Int
    let name: String
}

func process(_ items: [Product]) {
    for item in items {
        print("Processing \(item.name)")
    }
}

Suppose you are investigating a bug that only occurs for the product with an ID of 42.

Adding a breakpoint to the print statement stops for every product:

Processing Keyboard
Processing Mouse
Processing Monitor
Processing Headphones
...

That is useful for inspecting the flow, but not when you already know which value matters.

You want the debugger to stop here:

item.id == 42

Add a condition to a breakpoint

You can turn an ordinary breakpoint into a conditional one without changing your source code.

  1. Add a breakpoint to the line you want to inspect.
  2. Right-click the breakpoint in Xcode's breakpoint navigator or editor gutter.
  3. Choose Edit Breakpoint.
  4. Enter an expression in the Condition field.
  5. Click anywhere outside the popup to save it.
  6. Continue running your app.

For the example above, enter:

item.id == 42

Now Xcode evaluates that expression each time execution reaches the breakpoint.

The debugger pauses only when the condition is true.

Conceptually, the breakpoint changes from:

Stop here every time

to:

Stop here only when item.id == 42

This is especially useful when debugging loops, collection processing, delegates, callbacks, or frequently executed UI code.


Conditions can be more useful than a single ID

The condition does not have to be a simple equality check.

For example:

item.id > 100

Pause for products whose IDs are greater than 100.

You can combine multiple checks:

item.id == 42 && item.name.isEmpty

Pause only when the problematic product also has an empty name.

You can also use expressions involving other values that are available at that point in execution:

item.id == targetID

or:

item.isEnabled && item.count == 0

The important idea is that the expression should describe the bug state you are looking for.


Use a breakpoint action instead of stopping

Sometimes you don't want the debugger to pause at all.

You may simply want Xcode to perform an action when a particular condition occurs.

Right-click the breakpoint and choose Edit Breakpoint, then add a breakpoint action.

One useful option is Sound.

For example, you can configure a breakpoint to play a sound when execution reaches a particular location.

Combined with a condition, this becomes surprisingly useful:

item.id == 42

The debugger can alert you when the interesting state occurs without requiring you to constantly watch the application.

This is particularly handy when the code is executed frequently or when the interesting event happens after several seconds of interaction.


Combine a condition with a debugger action

Conditional breakpoints become even more powerful when you combine them with other breakpoint actions.

For example:

item.id == 42

Then configure an action such as:

  • Play a sound
  • Log a message
  • Run a debugger command
  • Pause execution

This lets the breakpoint act more like a small debugging rule:

When item.id == 42
        ↓
Perform an action
        ↓
Optionally pause

You can therefore investigate a very specific execution path without adding temporary logging throughout your code.


Conditions are especially useful for loops

One of the best places to use conditional breakpoints is inside loops.

Without a condition:

for item in items {
    // ⚠️ SET YOUR BREAKPOINT ON THE LINE BELOW ⚠️
    print("Processing \(item.name)")
}

The breakpoint may trigger hundreds or thousands of times.

With:

item.id == 42

you can jump directly to the iteration that matters.

You don't need to add:

if item.id == 42 {
    ...
}

to your production code just to help the debugger.

The filtering remains entirely within Xcode.


Don't modify your code just to debug

A common debugging technique is temporarily adding statements such as:

if item.id == 42 {
    print(item)
}

That works, but it changes the source code and adds noise that you later need to remove.

A conditional breakpoint keeps this investigation inside the debugger.

Your application code stays focused on application behavior, while Xcode handles the debugging condition.


Closing Thoughts

Conditional breakpoints are most useful when you know what state you are looking for, but not exactly when it will occur.

Instead of repeatedly stopping at the same line:

Breakpoint → Inspect → Continue
Breakpoint → Inspect → Continue
Breakpoint → Inspect → Continue

tell Xcode what matters:

item.id == 42

Then let the debugger wait for that state.

For frequently executed code, combine the condition with a breakpoint action such as a sound or debugger command. You can turn an ordinary breakpoint into a precise debugging trigger without adding temporary code to your app.

Next time a breakpoint fires too often, don't remove it - give it a condition.

Thank you for reading. If you have any questions feel free to follow me on X and send me a DM. If this article helped you, Buy me a coffee.