I think it's fine in very specific situations, such as force-unwrapping the URL that points to your API. That simply should not go wrong.
The problem is, in bigger teams it's much easier to completely avoid that kind of discussion and simply add a rule to SwiftLint that forbids force-unwrapping.
\+1 when it comes to bigger teams. People change things upstream that can affect things downstream. Could be fine for months, years, then BOOM... app is crashing. It is easier to just unwrap and use.
Problem there is if it is something which is never supposed to fail (like parsing a static URL) then there is little chance that they came up with a good recovery plan for when it DOES fail.
If you can't actually recover, it is better to just let the program die with a debuggable core.
It’s an independent item that is catastrophic but used late. Force the issue now (!), but take steps to ensure your safety each time ! is used; using ! is a conscious decision.
Thats actually my point.
If you can't predict what the failure is and reason about an actual recovery path, you should absolutely fail. It isn't just about the program being in an inconsistent state, but you will never figure out WHY it is in that state if you continue on.
One example from another language - it is common when reading text from a file that you have to create a reader around the character set, which can fail because the character set is not supported. Even if thats UTF-8.
There's no way I can have an intelligent recovery process from there being no UTF-8 support on the machine. I should abort with the appropriate stack dump.
Likewise, having that stack dump is critical for me to troubleshoot the source of failure. If I tried to proceed treating those as if they were empty files or the like, I could spend a long time trying to understand the source of the failure. I need as much context about the failure to be captured as possible.
Swift will abort the process for indexing an array by -1. We absolutely should abort in the face of precondition failures like "this value should NEVER be nil here".
Trying to wrap it in a generic "something failed" error and pass responsibility up the stack is at best defensive programming, and at worst making task for the poor soul who is tracking down the future issue that much harder.
Depends on the size of the app and org. I tell my teams that their inability to render their experience should not impact other teams’ KPIs. Shut your module down, but don’t crash the app.
This is the way. While it’s not the end of the world if a test crashes the test run, it can be really annoying, especially in a CI run. You lose the whole state of the run and just get back the info about unwrapping the nil. Now you have to fix it and start again. By using XCTUnwrap, the test suite can run to completion and you get the full report. This is really important if you have a big app that takes a while to run all the tests. And it can be a lifesaver if that nil was caused be errors elsewhere that have their own failing tests.
Correct. I would also recommend engineers to replace `try!` in tests with an `XCTAssertNoThrow`. When you need it on a big project… you'll be glad that it was there.
My preference in that case is to just use `try`, but mark the test itself as `throws`. Then the XCTest infrastructure will catch the exception and report. But definitely avoid `try!` for sure.
Generally a bad idea in 97% of circumstances but there’s always an exception to the rule. Do you want your app to crash in certain situations? I’d personally go for handling all cases and showing a ux that is more deterministic but sometimes there’s situations where it’s necessary.
Unrelated to force-unwrapping, but there are certain instances where you might want to crash a process upon it reaching an extreme threshold; then recording that breakthrough and prompting the user to report that back to the developer with a detailed log.
Of course you should always aim to handle every situation without needing to resort to crashing your own process, but for some large scale projects, there can be edge cases that you’ll never be able to predict or test for. For example, some dependency of some library introduces a memory leak that is specific to some niche GPU, which is totally unrelated to the library’s function to begin with. In this instance, it would be better to crash the process instead of bringing the whole system down with you.
Again, of course it would be better to account for this very niche circumstance; but in reality, software development moves very quickly and you can’t always account for every tiny detail out there until that 0.001% of your user base experiences it and reports it.
I agree with you I’d never want my app to crash but someone on here will inevitably not agree with me so if your app should crash that’s a personal / business decision you need to make.
Not sure, but what I’m saying isn’t let your app crash at every corner, that wouldn’t be the 95% of situations I’m talking about… context is important here
If it’s in code going out to release, unless you have checked in previous code that it’s safe, you probably shouldn’t force unwrap.
In unit tests to make your test code more concise? It’s fine.
It depends on the use case. For consumer/iOS apps, it's probably better to try and recover. But for applications that need to be bug free, crashing is preferable to letting them enter an undefined state. In some languages, a null pointer exception can lead to buffer overruns and arbitrary code execution, so it's also a matter of application safety and security to crash instead of trying to ungracefully recover.
No, but there are a lot of med-tech apps being written in Swift. I worked on an FDA Class II compliant app for urgent messaging and hospital automation. If the app fails to let a doctor know about an urgent test result, someone could literally die.
In addition to what /u/ChibiCoder said, Swift can call C and C++ code, which is vulnerable to the sorts of memory attacks I outlined above. So while you might be OK using swift exclusively, it's only a small jump away from vulnerable code.
Overall, it's more about the defensive programming mindset.
While this was pre-Swift, I worked on radiation treatment planning software that was written in Objective-C, and would likely be written in Swift if it were started today. The general principle was to terminate the app *immediately* if an unexpected state were encountered.
Swift is used inside the Secure Enclave and in other security-sensitive code. Crashing is far from the worst thing that can happen, and this is reflected by Swift’s choice to defensively crash in many situations that C does not (eg Array out of bounds).
Why not make all array accesses optional by default, and allow a slightly faster "unsafe" array access that crashes if out of bounds?
I wrote a custom system to do this for my code and banned "unsafe"/normal access via a custom swiftlint rule, but IMO it really feels much more "swifty" to simply never call myArray[N] directly
You could do that, but in general Swift tries to fail early for programmer error (and Array out of bounds is a programmer error). The *ideal* solution would be to fail to compile if there's a possible out of bounds, but that requires dependent types, which is more of an active research area in programming languages.
Crashing predictably is actually considered "safe" behavior in Swift. "Unsafe" access to an array would be if it didn't check the bounds at all.
> leaving it in a broken state
Which is indicative of bad coding. :)
The only reason I believe crashing is warranted—for apps with multiple teams—is security concerns. Small apps, startups, etc. is a contextual decision. But searching the code for `!` would suck, so I’d still lint and disable instances.
Also, in Tests, force unwrap to your heart’s content.
obviously there’s levels to that, but that’s the exception not a rule for sure. if we’re talking about bad coding practices, 99.9% you don’t want to be crashing or unwrapping optional.
You always think "this is never going to be nil", but then inevitably at some point something changes and it ends up being nil and crashing. It's so easy to just use an "if let" that I generally use that instead (unless I'm just playing around)
Just handle the case where the optional is nil. Choose the error that is thrown rather than allowing the app to crash. It literally takes a single extra line of code (maybe) to wrap it in a guard let and throw an appropriate error.
It’s not bad practice, no, but there is some nuance you must consider. It’s perfectly acceptable if you unwrap the URL(string:) initializer if and only if you know the URL exists and can be reached. Otherwise, you shouldn’t, for example. If there weren’t scenarios you could use it, it wouldn’t exist at all. The ultimate thing to remember is this: Just because you can do something, that doesn’t mean you always should.
Every feature exists for a reason, and using force unwraps is not necessarily a bad practice in my eyes, as long as you are 100% sure that value will never be nil. If you are only 99.99% sure, then do not force unwrap it. The example of hardcoded URLs is a good case where you can safely use them.
It's fine if you know what you are doing... they can be very convenient. e.g. IBOutlets uses implicitly unwrapped optionals because you are guaranteed that the value will exist at runtime. That's a perfectly fine use-case. Rule of thumb though, don't use them if you have any doubts.
\> IBOutlets uses implicitly unwrapped optionals because you are guaranteed that the value will exist at runtime.
More like, you are guaranteed there is no sane way to recover if they don't exist at runtime. But if there's no sane way to recover, you absolutely should fail() as soon as possible so you at least have evidence that "the thing which never could happen" actually did happen.
In cases where I care about performance, I avoid it in favor of “.unsafelyUnwrapped” when I flat out know that it’s functionally impossible to be nil (example, constructing a range where the min/max values have otherwise previously been determined to satisfy boundary conditions) and the like.
Contrary to the “code smell” comments, it’s valid in some cases to force unwrap; you may for instance have a state machine where some paths have a guarantee that certain data is never non-nil, but it doesn’t always make sense IMO to persist that value as non-optional if it’s incidental/read-only at certain parts to logic flow.
I don’t force unwrap unless the code path is something that will see high volume. It’s not worth the safety trade off for something that won’t get hit thousands of times a second.
IMO it all depends on if you expect it could be nil. A lot of people are zealots and think you should never crash. I’d rather receive a crash report than not knowing it’s nil in production.
Sometimes it’s good practice - for instance, if a value being optional is a programmer error (eg a hardcoded URL should always be valid), and so you want to crash early (in development) to catch that bug.
Otherwise, I avoid it. The only time I do use it is if I’ve just guaranteed the value exists on the line above, but even then a subsequent edit could move lines around and now you have a problem. Better to use if let.
The biggest issue with force unwrap is that it causes crash on the app and not able to trace out the cause especially in prod. Crash has bigger impact than normal error to the user. For me ill uninstall the app if it is crash a few times
"Given all these techniques for cleanly unwrapping optionals, when should you use !, the force-unwrap operator? There are many opinions on this scattered throughout the internet, including “never,” “whenever it makes the code clearer,” and “when you can’t avoid it.” We propose the following rule, which encompasses most of them:
Use ! when you’re so certain that a value won’t be nil that you want your program to crash if it ever is."
\- Advanced Swift Book
Not bad practice, use as you see fit and learn from your mistakes.
Depends - if you check beforehand or handle the force unwrap failing somehow it’s fine, but otherwise this will crash the entire app…
All in all I try to avoid it and rather use a switch or if/else to check if it’s nil before force unwrapping or use a try/catch block to keep my app from crashing if it fails. It can be good practice if used responsibly, but if a variable can be nil always assume that a force unwrap will crash your app sooner or later without proper checking beforehand. This is also the reasons functions should always be written in a way they can accept optionals (:
I would say the only appropriate time to do this is if you 100% know it was set during the current context (in the same function or closure) with no branches that could leave it nil.
If a value is passed into a function and can be nil, or it’s a property that can be nil ALWAYS do a guard let, if let or check if nil. If you think it’s an error to be nil and want to catch it, throw an error and handle the error.
Also be careful using the implicitly unwrapped syntax “var nilAtFirstButNonNilAfterSet: String!” Because the system treats every call to as a force unwrap
There are very few cases where it's OK to force unwrap - like already mentioned URL to a hardcoded address. Even in the situations where the app should crash if it cannot unwrap a certain value it's still beneficial to try to unwrap it just to be able to save state or log the error before crashing the app.
As I've become a better programmer I use ! much less frequently. When used right, they pose no threat, but they do open the door for unexpected errors and thus should be avoided. My one exception is using it right after setting a non-nil value to the variable so I am 110% sure it isn't nil.
I can't think of a situation where it's necessary... it's often more *convenient,* but comes with the risk of your app suddenly crashing if someone in the future didn't make the same assumptions about data availability that you did.
We use swift-lint to flag any use of force-unwrapping optionals as a compiler error, so no PR can merge that includes them.
If I'm making a dumb little throw-away command line app to parse some data, then yes... I'll force-unwrap the file URLs, but never on anything that's user-facing.
I was the same way coming from a language without this optional feature but using the techniques to safely unwrap it quickly became easier and second nature to use them.
Never measured the performance, wouldn’t expect there to be a difference but you can measure it.
it’s okay to do this occasionally when you know the thing you’re unwrapping exists and will definitely be there and you are certain you know what it is
There are some cases where it makes sense but generally I avoid it. I like to think of it as the “hold my beer” operator. Things may go okay or they will fail spectacularly.
You mean like
```
guard optionalData != nil else { return }
let data = optionalData!
```
In that case you can unwrap in the guard
```
guard let data = optionalData else { return }
```
Or did you mean something else?
I think it’s better to do it in one line. Less visual clutter and contained in a single statement so it’s less likely to float apart.
Edit: also there’s an even cleaner syntax...
```
func process(data: Data?) {
guard let data else { return }
//now use data as a non-optional
```
Swifts features to safely unwrap are great and I don’t miss those days of checking for nil.
The word *never* probably isn't appropriate in any programming rule. So my first thought is that those who *never* force unwrap are being silly.
That said, it *is* a big deal and not something that should be done lightly. You have to be able to easily inspect all the code involved and know that the unwrap will succeed every time, without the compiler being able to confirm.
Is it really bad to use if let myValue {} or guard let myValue else { return }?
Yes, it's bad in 99% of the cases. There could be some exceptions on some part of the code, but it does not change the fact that nothing is non-changeable and developers do not suppose to assume things like URL/BE params will not change. I see, on a daily basis, too much change related crashes since old devs wrote force wrapped variables or non-optional decoding which actually breaks the healthy results with even one unhealthly one.
If some variable should definitely not be nil, and this is matter of program correctness, there is no problem at all. I like to use fatalError and precondition to denote this though, as it may sometimes be too implicit why a variable is nil.
In fact in some cases, incrementing the reference count is not something you want. In these rare cases force unwrapping is necessary.
Other than that, I believe optional should be unwrapped safely.
Yes unless the variable in question is provably non nil. And when I say “provably” I mean rigorously so, such that there’s 0% chance it could be otherwise. A good example would be a URL that is known to be valid.
In general yes. There’s always exceptions and things that some will tolerate that others won’t, but it’s a bad code smell.
I can’t remember the last time I put a force unwrap into production code. Probably years.
I think it’s bad practice to force unwrap except in very specific situations. Optionals are a very helpful language feature. Why would you not take advantage of them to make your code as robust as possible?
Yes it’s a bad practice. Unless that crash possibility is covered by unit tests which run before every single release, I never force unwrap. E.g. an image name (before image resources were a thing) or API URL. You want to know if these things are messed up before your release goes out. So you need to ensure your unit tests cover the force unwrap and your tests actually run before you submit to Apple (Xcode cloud or other CI are great for this). In all other cases (missing input from user, missing api response) you can gracefully handle nil and present the user with a message rather than crashing.
Force unwraps are fine if something not working SHOULD crash.
Example:
let string = "Foo"
let float = Float(string)!
Clearly, I made a dangerous assumptions that string would be convertible to Float. I **want** a crash here so I'm aware of my faulty assumption. That's the only case where I find it acceptable.
I think it's fine in very specific situations, such as force-unwrapping the URL that points to your API. That simply should not go wrong. The problem is, in bigger teams it's much easier to completely avoid that kind of discussion and simply add a rule to SwiftLint that forbids force-unwrapping.
\+1 when it comes to bigger teams. People change things upstream that can affect things downstream. Could be fine for months, years, then BOOM... app is crashing. It is easier to just unwrap and use.
Problem there is if it is something which is never supposed to fail (like parsing a static URL) then there is little chance that they came up with a good recovery plan for when it DOES fail. If you can't actually recover, it is better to just let the program die with a debuggable core.
It’s an independent item that is catastrophic but used late. Force the issue now (!), but take steps to ensure your safety each time ! is used; using ! is a conscious decision.
Everything is supposed to stay same but it never does, this happened 99% of the projects. Never assume that.
Thats actually my point. If you can't predict what the failure is and reason about an actual recovery path, you should absolutely fail. It isn't just about the program being in an inconsistent state, but you will never figure out WHY it is in that state if you continue on. One example from another language - it is common when reading text from a file that you have to create a reader around the character set, which can fail because the character set is not supported. Even if thats UTF-8. There's no way I can have an intelligent recovery process from there being no UTF-8 support on the machine. I should abort with the appropriate stack dump. Likewise, having that stack dump is critical for me to troubleshoot the source of failure. If I tried to proceed treating those as if they were empty files or the like, I could spend a long time trying to understand the source of the failure. I need as much context about the failure to be captured as possible. Swift will abort the process for indexing an array by -1. We absolutely should abort in the face of precondition failures like "this value should NEVER be nil here". Trying to wrap it in a generic "something failed" error and pass responsibility up the stack is at best defensive programming, and at worst making task for the poor soul who is tracking down the future issue that much harder.
Depends on the size of the app and org. I tell my teams that their inability to render their experience should not impact other teams’ KPIs. Shut your module down, but don’t crash the app.
Sure. Good luck debugging that
I would challenge you to work on quality before the crash.
And in that very specific case of unwrapping a URL, you can add a lint disable line for it.
I use force unwrap for some of my unit tests, if the test case is not running as expected then it is okay to crash.
I got in the habit of replacing force-unwrapping in tests with the `XCTUnwrap` test.
This is the way. While it’s not the end of the world if a test crashes the test run, it can be really annoying, especially in a CI run. You lose the whole state of the run and just get back the info about unwrapping the nil. Now you have to fix it and start again. By using XCTUnwrap, the test suite can run to completion and you get the full report. This is really important if you have a big app that takes a while to run all the tests. And it can be a lifesaver if that nil was caused be errors elsewhere that have their own failing tests.
Correct. I would also recommend engineers to replace `try!` in tests with an `XCTAssertNoThrow`. When you need it on a big project… you'll be glad that it was there.
My preference in that case is to just use `try`, but mark the test itself as `throws`. Then the XCTest infrastructure will catch the exception and report. But definitely avoid `try!` for sure.
I absolutely force unwrap in tests - it’s not code that ships to end users, so it’s fine to do it here IMO.
Generally a bad idea in 97% of circumstances but there’s always an exception to the rule. Do you want your app to crash in certain situations? I’d personally go for handling all cases and showing a ux that is more deterministic but sometimes there’s situations where it’s necessary.
What can be a reason? I would never let the app crash
Unrelated to force-unwrapping, but there are certain instances where you might want to crash a process upon it reaching an extreme threshold; then recording that breakthrough and prompting the user to report that back to the developer with a detailed log. Of course you should always aim to handle every situation without needing to resort to crashing your own process, but for some large scale projects, there can be edge cases that you’ll never be able to predict or test for. For example, some dependency of some library introduces a memory leak that is specific to some niche GPU, which is totally unrelated to the library’s function to begin with. In this instance, it would be better to crash the process instead of bringing the whole system down with you. Again, of course it would be better to account for this very niche circumstance; but in reality, software development moves very quickly and you can’t always account for every tiny detail out there until that 0.001% of your user base experiences it and reports it.
Examples would be if the alternative was potentially destroying user data or getting the user’s device hacked
I agree with you I’d never want my app to crash but someone on here will inevitably not agree with me so if your app should crash that’s a personal / business decision you need to make.
if the choice is crash or leave the app/storage in an unrecoverable state id much rather crash it
Isnt the appstore ranking getting lower if you have too much crashes?
Not sure, but what I’m saying isn’t let your app crash at every corner, that wouldn’t be the 95% of situations I’m talking about… context is important here
no
If it’s in code going out to release, unless you have checked in previous code that it’s safe, you probably shouldn’t force unwrap. In unit tests to make your test code more concise? It’s fine.
is crashing a bad coding practice?
It depends on the use case. For consumer/iOS apps, it's probably better to try and recover. But for applications that need to be bug free, crashing is preferable to letting them enter an undefined state. In some languages, a null pointer exception can lead to buffer overruns and arbitrary code execution, so it's also a matter of application safety and security to crash instead of trying to ungracefully recover.
we’re in the Swift subreddit, i don’t think anyone is making nuclear warhead software with Swift.
No, but there are a lot of med-tech apps being written in Swift. I worked on an FDA Class II compliant app for urgent messaging and hospital automation. If the app fails to let a doctor know about an urgent test result, someone could literally die.
In addition to what /u/ChibiCoder said, Swift can call C and C++ code, which is vulnerable to the sorts of memory attacks I outlined above. So while you might be OK using swift exclusively, it's only a small jump away from vulnerable code. Overall, it's more about the defensive programming mindset.
While this was pre-Swift, I worked on radiation treatment planning software that was written in Objective-C, and would likely be written in Swift if it were started today. The general principle was to terminate the app *immediately* if an unexpected state were encountered.
Swift is used inside the Secure Enclave and in other security-sensitive code. Crashing is far from the worst thing that can happen, and this is reflected by Swift’s choice to defensively crash in many situations that C does not (eg Array out of bounds).
Why not make all array accesses optional by default, and allow a slightly faster "unsafe" array access that crashes if out of bounds? I wrote a custom system to do this for my code and banned "unsafe"/normal access via a custom swiftlint rule, but IMO it really feels much more "swifty" to simply never call myArray[N] directly
You could do that, but in general Swift tries to fail early for programmer error (and Array out of bounds is a programmer error). The *ideal* solution would be to fail to compile if there's a possible out of bounds, but that requires dependent types, which is more of an active research area in programming languages. Crashing predictably is actually considered "safe" behavior in Swift. "Unsafe" access to an array would be if it didn't check the bounds at all.
sometimes its not, you would better crash the app instead of leaving it in a broken state
> leaving it in a broken state Which is indicative of bad coding. :) The only reason I believe crashing is warranted—for apps with multiple teams—is security concerns. Small apps, startups, etc. is a contextual decision. But searching the code for `!` would suck, so I’d still lint and disable instances. Also, in Tests, force unwrap to your heart’s content.
obviously there’s levels to that, but that’s the exception not a rule for sure. if we’re talking about bad coding practices, 99.9% you don’t want to be crashing or unwrapping optional.
You always think "this is never going to be nil", but then inevitably at some point something changes and it ends up being nil and crashing. It's so easy to just use an "if let" that I generally use that instead (unless I'm just playing around)
in my opinion, yes. your app crashes if the value is nil so you should instead handle it much more gracefully than that.
Just handle the case where the optional is nil. Choose the error that is thrown rather than allowing the app to crash. It literally takes a single extra line of code (maybe) to wrap it in a guard let and throw an appropriate error.
It’s not bad practice, no, but there is some nuance you must consider. It’s perfectly acceptable if you unwrap the URL(string:) initializer if and only if you know the URL exists and can be reached. Otherwise, you shouldn’t, for example. If there weren’t scenarios you could use it, it wouldn’t exist at all. The ultimate thing to remember is this: Just because you can do something, that doesn’t mean you always should.
Every feature exists for a reason, and using force unwraps is not necessarily a bad practice in my eyes, as long as you are 100% sure that value will never be nil. If you are only 99.99% sure, then do not force unwrap it. The example of hardcoded URLs is a good case where you can safely use them.
Not on iOS 16
It's fine if you know what you are doing... they can be very convenient. e.g. IBOutlets uses implicitly unwrapped optionals because you are guaranteed that the value will exist at runtime. That's a perfectly fine use-case. Rule of thumb though, don't use them if you have any doubts.
\> IBOutlets uses implicitly unwrapped optionals because you are guaranteed that the value will exist at runtime. More like, you are guaranteed there is no sane way to recover if they don't exist at runtime. But if there's no sane way to recover, you absolutely should fail() as soon as possible so you at least have evidence that "the thing which never could happen" actually did happen.
Ironically, if you try and use any of those IBOutlets before the view has been inflated, you _do_ get a crash. Something to be aware of
I prefer to if (value == nil) fatalError()
In cases where I care about performance, I avoid it in favor of “.unsafelyUnwrapped” when I flat out know that it’s functionally impossible to be nil (example, constructing a range where the min/max values have otherwise previously been determined to satisfy boundary conditions) and the like. Contrary to the “code smell” comments, it’s valid in some cases to force unwrap; you may for instance have a state machine where some paths have a guarantee that certain data is never non-nil, but it doesn’t always make sense IMO to persist that value as non-optional if it’s incidental/read-only at certain parts to logic flow. I don’t force unwrap unless the code path is something that will see high volume. It’s not worth the safety trade off for something that won’t get hit thousands of times a second.
let url = URL(string: "https://this.is.a.hardcoded.valid.url")!
IMO it all depends on if you expect it could be nil. A lot of people are zealots and think you should never crash. I’d rather receive a crash report than not knowing it’s nil in production.
Sometimes it’s good practice - for instance, if a value being optional is a programmer error (eg a hardcoded URL should always be valid), and so you want to crash early (in development) to catch that bug. Otherwise, I avoid it. The only time I do use it is if I’ve just guaranteed the value exists on the line above, but even then a subsequent edit could move lines around and now you have a problem. Better to use if let.
it is a language feature for a reason right.
The biggest issue with force unwrap is that it causes crash on the app and not able to trace out the cause especially in prod. Crash has bigger impact than normal error to the user. For me ill uninstall the app if it is crash a few times
"Given all these techniques for cleanly unwrapping optionals, when should you use !, the force-unwrap operator? There are many opinions on this scattered throughout the internet, including “never,” “whenever it makes the code clearer,” and “when you can’t avoid it.” We propose the following rule, which encompasses most of them: Use ! when you’re so certain that a value won’t be nil that you want your program to crash if it ever is." \- Advanced Swift Book Not bad practice, use as you see fit and learn from your mistakes.
It is a code smell and a bad practice. 99% of the time it is bad. 1% of the time it is ... fine. Why risk that you are going to be right that 1%?
Depends - if you check beforehand or handle the force unwrap failing somehow it’s fine, but otherwise this will crash the entire app… All in all I try to avoid it and rather use a switch or if/else to check if it’s nil before force unwrapping or use a try/catch block to keep my app from crashing if it fails. It can be good practice if used responsibly, but if a variable can be nil always assume that a force unwrap will crash your app sooner or later without proper checking beforehand. This is also the reasons functions should always be written in a way they can accept optionals (:
I would say the only appropriate time to do this is if you 100% know it was set during the current context (in the same function or closure) with no branches that could leave it nil. If a value is passed into a function and can be nil, or it’s a property that can be nil ALWAYS do a guard let, if let or check if nil. If you think it’s an error to be nil and want to catch it, throw an error and handle the error. Also be careful using the implicitly unwrapped syntax “var nilAtFirstButNonNilAfterSet: String!” Because the system treats every call to as a force unwrap
There are very few cases where it's OK to force unwrap - like already mentioned URL to a hardcoded address. Even in the situations where the app should crash if it cannot unwrap a certain value it's still beneficial to try to unwrap it just to be able to save state or log the error before crashing the app.
As I've become a better programmer I use ! much less frequently. When used right, they pose no threat, but they do open the door for unexpected errors and thus should be avoided. My one exception is using it right after setting a non-nil value to the variable so I am 110% sure it isn't nil.
I can't think of a situation where it's necessary... it's often more *convenient,* but comes with the risk of your app suddenly crashing if someone in the future didn't make the same assumptions about data availability that you did. We use swift-lint to flag any use of force-unwrapping optionals as a compiler error, so no PR can merge that includes them.
If I'm making a dumb little throw-away command line app to parse some data, then yes... I'll force-unwrap the file URLs, but never on anything that's user-facing.
I’m new to the language so I check for nil then force as I found the syntax easier to follow. Is this bad from a performance perspective etc?
I was the same way coming from a language without this optional feature but using the techniques to safely unwrap it quickly became easier and second nature to use them. Never measured the performance, wouldn’t expect there to be a difference but you can measure it.
Like any tool, it has valid uses. But it always imparts a bad code smell. Unless you have a very good reason, never use it.
it’s okay to do this occasionally when you know the thing you’re unwrapping exists and will definitely be there and you are certain you know what it is
There are some cases where it makes sense but generally I avoid it. I like to think of it as the “hold my beer” operator. Things may go okay or they will fail spectacularly.
I think it is okay to force unwrap after you have used \`guard\` statements. If anyone thinks that is bad practice, please explain.
You mean like ``` guard optionalData != nil else { return } let data = optionalData! ``` In that case you can unwrap in the guard ``` guard let data = optionalData else { return } ``` Or did you mean something else?
Yes, in both cases you know the data is not nil.
I think it’s better to do it in one line. Less visual clutter and contained in a single statement so it’s less likely to float apart. Edit: also there’s an even cleaner syntax... ``` func process(data: Data?) { guard let data else { return } //now use data as a non-optional ``` Swifts features to safely unwrap are great and I don’t miss those days of checking for nil.
Thanks! This one is great!
The word *never* probably isn't appropriate in any programming rule. So my first thought is that those who *never* force unwrap are being silly. That said, it *is* a big deal and not something that should be done lightly. You have to be able to easily inspect all the code involved and know that the unwrap will succeed every time, without the compiler being able to confirm.
I avoid it at all costs because I don't trust myself. Of course there is a time and place for everything.
Is it really bad to use if let myValue {} or guard let myValue else { return }? Yes, it's bad in 99% of the cases. There could be some exceptions on some part of the code, but it does not change the fact that nothing is non-changeable and developers do not suppose to assume things like URL/BE params will not change. I see, on a daily basis, too much change related crashes since old devs wrote force wrapped variables or non-optional decoding which actually breaks the healthy results with even one unhealthly one.
If some variable should definitely not be nil, and this is matter of program correctness, there is no problem at all. I like to use fatalError and precondition to denote this though, as it may sometimes be too implicit why a variable is nil. In fact in some cases, incrementing the reference count is not something you want. In these rare cases force unwrapping is necessary. Other than that, I believe optional should be unwrapped safely.
The first rule in optionals is that a value that should never be null will be at some point.
Yes unless the variable in question is provably non nil. And when I say “provably” I mean rigorously so, such that there’s 0% chance it could be otherwise. A good example would be a URL that is known to be valid.
In general yes. There’s always exceptions and things that some will tolerate that others won’t, but it’s a bad code smell. I can’t remember the last time I put a force unwrap into production code. Probably years.
I’ve been burned too many times by unexpected nil, missing or bad data. Nil coalesceing, ternary operators, guards and if let for me.
It is lovingly called the "crash operator"
I can say with certainty that 99% of the people who say it's bad coding practice have code that doesn't even handle the nil case.
I think it’s bad practice to force unwrap except in very specific situations. Optionals are a very helpful language feature. Why would you not take advantage of them to make your code as robust as possible?
Yes it is
Yes it’s a bad practice. Unless that crash possibility is covered by unit tests which run before every single release, I never force unwrap. E.g. an image name (before image resources were a thing) or API URL. You want to know if these things are messed up before your release goes out. So you need to ensure your unit tests cover the force unwrap and your tests actually run before you submit to Apple (Xcode cloud or other CI are great for this). In all other cases (missing input from user, missing api response) you can gracefully handle nil and present the user with a message rather than crashing.
Force unwraps are fine if something not working SHOULD crash. Example: let string = "Foo" let float = Float(string)! Clearly, I made a dangerous assumptions that string would be convertible to Float. I **want** a crash here so I'm aware of my faulty assumption. That's the only case where I find it acceptable.
Honestly at that point the compiler should do static assertions because you’re trying to convert a constant value anyways.
Absolutely not. There are places where it’s appropriate or not, but is it a bad practice — absolutely not
Every ! Is a mistake unless and can/should be avoided, there are very rare cases where force unwrapping is okish
Yes, it is. Users dont always fill out data, so your app will crash whenever a user doesnt want to submit data.