Preface
In Swift, ENABLE_NS_ASSERTIONS
is ignored, and whether assertions are on or off is dependent of SWIFT_OPTIMIZATION_LEVEL
, see here for more information.
assert()
is active for -Onone
assertionFailure()
is active for
-Onone
precondition()
is active for -Onone
and -O
preconditionFailure()
is active for -Onone
, -O
and -Ounchecked
fatalError()
is active for -Onone
, -O
and -Ounchecked
What I want to achieve
Debug and Beta Builds should have assertions enabled, Release Builds should have assertions disabled.
How I could do it
I could write all my assertions in Swift via the precondition
method and compile Release builds with the -Ounchecked
flag, beta builds with the -O
flag.
What I'm unsure about
The default in iOS for Release builds is -O
. Is there anything advised against using -Ounchecked
for release builds? Which other unwanted side effects could this cause?
You should definitely not compile -Ounchecked
for release in order to use precondition
only while testing. Compiling -Ounchecked
also disables checks for things like array out of bounds and unwrapping nil
, that could lead to some pretty nasty production bugs involving memory corruption.
You can control assertion behaviour independently of compiler optimization settings via the -assert-config
argument to swiftc
:
$ cat assert.swift
assert(false, "assertion asserted")
println("made it here...")
$ swiftc -Onone assert.swift; ./assert
assertion failed: assertion asserted: file assert.swift, line 1
Illegal instruction: 4
$ swiftc -O assert.swift; ./assert
made it here...
$ swiftc -O -assert-config Debug assert.swift; ./assert
assertion failed: assertion asserted: file assert.swift, line 1
Illegal instruction: 4
$
It doesn’t look like there’s an Xcode Build Settings toggle for this, but you can add using the “Other Swift Flags” setting.