optional closure and check if it is nil
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Swift, a closure can be optional just like any other value. That means the closure may or may not exist, and the caller has to deal with that possibility safely. The most idiomatic approach is usually not to write a long manual nil check, but to use optional chaining or optional binding depending on whether you only want to call the closure or also need to inspect it first.
Declare an Optional Closure
An optional closure type looks like this:
That means completion is either:
- a closure that takes no arguments and returns
Void - or
nil
The same idea works for closures with parameters:
Now the closure may accept a String, but it is still optional.
Call It with Optional Chaining
If you only want to call the closure when it exists, optional chaining is the cleanest pattern.
If completion is nil, nothing happens. If it contains a closure, Swift calls it.
This is usually better than writing a verbose nil check for simple callback execution.
Use if let When You Need the Closure Value
If you need to hold onto the closure briefly, log something, or call it several times in the same block, bind it first.
This is also useful if the code would be harder to read with repeated optional chaining.
Checking Whether It Is Nil
If you specifically need to know whether the optional closure is present, compare it to nil.
That is fine when the presence or absence itself affects control flow. But if the only goal is to call it when available, completion?() is still the more idiomatic form.
Optional Closures as Function Parameters
Optional closures are common in APIs where a completion handler is allowed but not required.
This combines an optional closure with a default value of nil, making the callback truly optional for the caller.
Escaping Closures Still Work the Same Way
If the closure is stored or used later, it may still need @escaping even when it is optional.
Optionality and escaping solve different problems:
- optionality means the closure may be absent
- escaping means the closure may outlive the current function call
It helps to keep those concerns separate.
Avoid Force-Unwrapping Optional Closures
This is legal but risky:
If completion is nil, the program crashes. Force-unwrapping is only reasonable when some earlier guarantee makes nil impossible and that guarantee is truly solid. In ordinary Swift code, optional chaining is the safer default.
When a Non-Optional Closure Is Better
Sometimes the real answer is not an optional closure at all. If the closure is always required for correct behavior, make it non-optional and force callers to supply it.
This simplifies the API and removes one whole category of nil-handling logic.
Common Pitfalls
- Writing manual nil checks when
closure?()would be clearer. - Force-unwrapping an optional closure and risking a crash.
- Treating
@escapingand optionality as if they solved the same problem. - Making a closure optional when the API really requires it.
- Forgetting that optional closures can still be stored, passed around, and called later like any other optional value.
Summary
- An optional closure in Swift is just a closure value that may also be
nil. - Use optional chaining such as
completion?()when you only need to call it if present. - Use
if letwhen you need to bind the closure and work with it explicitly. - Avoid force-unwrapping unless absence is truly impossible.
- If the callback is required, make it non-optional instead of modeling it as maybe missing.

