I have several assert(condition, "message")
statements in my project.
They are used to check invariant conditions during development. I thought they would be ignored in production/release build (as stated in this answer). They are not. Instead they cause crashes during TestFlight testing. When I comment asserts the app does not crash. Something usually gets wrong a bit but it does not crash.
Can it be something with my build settings?
All my archive schemes use release configuration:
The asserts are in Cocoa Touch Framework project, that is used from custom keyboard extension.
All the targets in all projects (Cocoa Touch Framework, and the main project with keyboard extension target) have these Build Settings:
Enable Foundation Assertions
Debug YES
Release NO
Disable Safety Checks NO
What's wrong?
EDIT:
Sulthan's answer shows how to disable asserts globally for both debug and relase builds. That is not what I need. I want it to work as expected - asserts should be enabled in debug but disabled in release builds.
By default it works that way - and it also works that way in my main project. But it does not work for asserts located in Framework project that is linked from that main project (details in this question). Why? How to fix it?
Assert is a tool. The purpose of this tool is to halt your program in DEBUG and indicate that a condition you have stated should never be false is, indeed, false. This allows you to debug your code before you hand it to your professor.
In the Java guideline, it is said that "assertions are only intended for debugging and bug hunting, but should be removed in production code".
As you can see assert() takes two parameters: something to check, and a message to print out of the check fails. If the check evaluates to false, your app will be forced to crash because you know it's not in a safe state, and you'll see the error message in the debug console.
One step up from assert() is assertionFailure() , which no longer has a condition: it will always crash your app when the function is called, printing any message you provide. As with assert() this will only ever be used in debug builds, so you don't have to worry about this in release mode.
The options you have tried:
Enable Foundation Assertions
is in the preprocessing section (Macros). Swift is not preprocessed and does not use macros. This option disables NSAssert
, NSParameterAssert
and similar macros commonly used in Objective-C.
Disable Safety Checks
is a performance option:
By default, the standard library guarantees memory safety. Many functions and methods document the requirements that must be satisfied by the caller, such as an array index being valid; memory safety is guaranteed even if a requirement is violated. However, violating a requirement can trigger a runtime error. APIs that include the word “unsafe” in their name let you explicitly disable safety checks in places where you need the additional performance. It’s your responsibility to verify the memory safety of code that uses unsafe APIs. Memory safety is also not guaranteed if there is a race condition in multithreaded code.
(Swift Library Reference)
You should probably try my answer here
(use -assert-config Release
in Other Swift Flags
).
Or just keep the asserts in production builds. Every failing assert is a bug and in general it's better to know about a bug as soon as possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With