TL;DR
I recently converted all the Objective-C libraries I am working on to SPM (using mostly SPM 5.3), but I just discovered that NSAssert
s are not stripped out from release builds. This can lead to crashes in production code.
The situation is different with assert
s in Swift package products since these assertions are stripped depending on the code optimization level, thus usually removed from release builds.
Is this desired behavior or was something missed in the case of Objective-C?
Thanks in advance for helping me understand this behavior.
Behavior in good old Xcode projects
If you create a project with Xcode, whether for an app, static lib or framework target, Xcode sets the ENABLE_NS_ASSERTIONS
preprocessor flag by default only for debug builds. This means the NS_BLOCK_ASSERTIONS
flag is set in release builds, disabling NSAssert
macros.
This behavior is of course the default one but you can still change it if you want.
Behavior with Objective-C package products
Looking at an Objective-C package build log you can see that a package built in release mode does not have the NS_BLOCK_ASSERTIONS
flag set and thus still contain NSAssert
s.
Disabling assertions in a package manifest
It is of course possible to disable assertions in release builds:
.target(
name: "MyPackage",
cSettings: [
.define("NS_BLOCK_ASSERTIONS", to: "1", .when(configuration: .release))
]
)
This of course requires you to have access to the package manifest.