Wednesday, October 28, 2026
HomeiOS Developmentswift - What does "Deadly error: Unexpectedly discovered nil whereas unwrapping an...

swift – What does “Deadly error: Unexpectedly discovered nil whereas unwrapping an Non-obligatory worth” imply?

[ad_1]

Background: What’s an Non-obligatory?

In Swift, Non-obligatory<Wrapped> is an possibility sort: it could include any worth from the unique (“Wrapped”) sort, or no worth in any respect (the particular worth nil). An elective worth should be unwrapped earlier than it may be used.

Non-obligatory is a generic sort, which signifies that Non-obligatory<Int> and Non-obligatory<String> are distinct varieties — the kind inside <> is known as the Wrapped sort. Underneath the hood, an Non-obligatory is an enum with two instances: .some(Wrapped) and .none, the place .none is equal to nil.

Optionals could be declared utilizing the named sort Non-obligatory<T>, or (mostly) as a shorthand with a ? suffix.

var anInt: Int = 42
var anOptionalInt: Int? = 42
var anotherOptionalInt: Int?  // `nil` is the default when no worth is offered
var aVerboseOptionalInt: Non-obligatory<Int>  // equal to `Int?`

anOptionalInt = nil // now this variable incorporates nil as a substitute of an integer

Optionals are a easy but highly effective device to specific your assumptions whereas writing code. The compiler can use this data to forestall you from making errors. From The Swift Programming Language:

Swift is a type-safe language, which implies the language lets you be clear in regards to the varieties of values your code can work with. If a part of your code requires a String, sort security prevents you from passing it an Int by mistake. Likewise, sort security prevents you from by chance passing an elective String to a chunk of code that requires a non-optional String. Kind security helps you catch and repair errors as early as attainable within the improvement course of.

Another programming languages even have generic possibility varieties: for instance, Perhaps in Haskell, possibility in Rust, and elective in C++17.

In programming languages with out possibility varieties, a specific “sentinel” worth is commonly used to point the absence of a legitimate worth. In Goal-C, for instance, nil (the null pointer) represents the shortage of an object. For primitive varieties reminiscent of int, a null pointer cannot be used, so that you would wish both a separate variable (reminiscent of worth: Int and isValid: Bool) or a delegated sentinel worth (reminiscent of -1 or INT_MIN). These approaches are error-prone as a result of it is easy to overlook to examine isValid or to examine for the sentinel worth. Additionally, if a specific worth is chosen because the sentinel, meaning it could now not be handled as a legitimate worth.

Choice varieties reminiscent of Swift’s Non-obligatory clear up these issues by introducing a particular, separate nil worth (so you do not have to designate a sentinel worth), and by leveraging the robust sort system so the compiler will help you bear in mind to examine for nil when mandatory.


Why did I get “Deadly error: Unexpectedly discovered nil whereas unwrapping an Non-obligatory worth”?

With the intention to entry an elective’s worth (if it has one in any respect), you’ll want to unwrap it. An elective worth could be unwrapped safely or forcibly. If you happen to force-unwrap an elective, and it did not have a worth, your program will crash with the above message.

Xcode will present you the crash by highlighting a line of code. The issue happens on this line.

crashed line

This crash can happen with two completely different sorts of force-unwrap:

1. Specific Pressure Unwrapping

That is executed with the ! operator on an elective. For instance:

let anOptionalString: String?
print(anOptionalString!) // <- CRASH

Deadly error: Unexpectedly discovered nil whereas unwrapping an Non-obligatory worth

As anOptionalString is nil right here, you’re going to get a crash on the road the place you pressure unwrap it.

2. Implicitly Unwrapped Optionals

These are outlined with a !, relatively than a ? after the kind.

var optionalDouble: Double!   // this worth is implicitly unwrapped wherever it is used

These optionals are assumed to include a worth. Due to this fact everytime you entry an implicitly unwrapped elective, it would routinely be pressure unwrapped for you. If it doesn’t include a worth, it would crash.

print(optionalDouble) // <- CRASH

Deadly error: Unexpectedly discovered nil whereas implicitly unwrapping an Non-obligatory worth

With the intention to work out which variable prompted the crash, you may maintain ⌥ whereas clicking to indicate the definition, the place you may discover the elective sort.

IBOutlets, particularly, are often implicitly unwrapped optionals. It’s because your xib or storyboard will hyperlink up the shops at runtime, after initialization. It is best to subsequently be certain that you’re not accessing shops earlier than they’re loaded in. You additionally ought to examine that the connections are appropriate in your storyboard/xib file, in any other case the values will probably be nil at runtime, and subsequently crash when they’re implicitly unwrapped. When fixing connections, strive deleting the strains of code that outline your shops, then reconnect them.


When ought to I ever pressure unwrap an Non-obligatory?

Specific Pressure Unwrapping

As a normal rule, you need to by no means explicitly pressure unwrap an elective with the ! operator. There could also be instances the place utilizing ! is appropriate – however you need to solely ever be utilizing it in case you are 100% certain that the elective incorporates a worth.

Whereas there might be an event the place you should use pressure unwrapping, as you realize for a reality that an elective incorporates a worth – there may be not a single place the place you can not safely unwrap that elective as a substitute.

Implicitly Unwrapped Optionals

These variables are designed as a way to defer their task till later in your code. It’s your duty to make sure they’ve a worth earlier than you entry them. Nonetheless, as a result of they contain pressure unwrapping, they’re nonetheless inherently unsafe – as they assume your worth is non-nil, regardless that assigning nil is legitimate.

It is best to solely be utilizing implicitly unwrapped optionals as a final resort. If you should use a lazy variable, or present a default worth for a variable – you need to accomplish that as a substitute of utilizing an implicitly unwrapped elective.

Nonetheless, there are a few situations the place implicitly unwrapped optionals are useful, and you’re nonetheless ready to make use of varied methods of safely unwrapping them as listed under – however you need to at all times use them with due warning.


How can I safely take care of Optionals?

The best method to examine whether or not an elective incorporates a worth, is to match it to nil.

if anOptionalInt != nil {
    print("Incorporates a worth!")
} else {
    print("Doesn’t include a worth.")
}

Nonetheless, 99.9% of the time when working with optionals, you’ll really need to entry the worth it incorporates, if it incorporates one in any respect. To do that, you should use Non-obligatory Binding.

Non-obligatory Binding

Non-obligatory Binding means that you can examine if an elective incorporates a worth – and means that you can assign the unwrapped worth to a brand new variable or fixed. It makes use of the syntax if let x = anOptional {...} or if var x = anOptional {...}, relying if you’ll want to modify the worth of the brand new variable after binding it.

For instance:

if let quantity = anOptionalInt {
    print("Incorporates a worth! It's (quantity)!")
} else {
    print("Doesn’t include a quantity")
}

What this does is first examine that the elective incorporates a worth. If it does, then the ‘unwrapped’ worth is assigned to a brand new variable (quantity) – which you’ll then freely use as if it have been non-optional. If the elective doesn’t include a worth, then the else clause will probably be invoked, as you’d anticipate.

What’s neat about elective binding, is you may unwrap a number of optionals on the similar time. You may simply separate the statements with a comma. The assertion will succeed if all of the optionals have been unwrapped.

var anOptionalInt : Int?
var anOptionalString : String?

if let quantity = anOptionalInt, let textual content = anOptionalString {
    print("anOptionalInt incorporates a worth: (quantity). And so does anOptionalString, it’s: (textual content)")
} else {
    print("A number of of the optionals don’t include a worth")
}

One other neat trick is which you could additionally use commas to examine for a sure situation on the worth, after unwrapping it.

if let quantity = anOptionalInt, quantity > 0 {
    print("anOptionalInt incorporates a worth: (quantity), and it’s larger than zero!")
}

The one catch with utilizing elective binding inside an if assertion, is which you could solely entry the unwrapped worth from throughout the scope of the assertion. If you happen to want entry to the worth from exterior of the scope of the assertion, you should use a guard assertion.

A guard assertion means that you can outline a situation for achievement – and the present scope will solely proceed executing if that situation is met. They’re outlined with the syntax guard situation else {...}.

So, to make use of them with an elective binding, you are able to do this:

guard let quantity = anOptionalInt else {
    return
}

(Word that throughout the guard physique, you should use one of many management switch statements as a way to exit the scope of the presently executing code).

If anOptionalInt incorporates a worth, it will likely be unwrapped and assigned to the brand new quantity fixed. The code after the guard will then proceed executing. If it doesn’t include a worth – the guard will execute the code throughout the brackets, which is able to result in switch of management, in order that the code instantly after won’t be executed.

The actual neat factor about guard statements is the unwrapped worth is now out there to make use of in code that follows the assertion (as we all know that future code can solely execute if the elective has a worth). This can be a nice for eliminating ‘pyramids of doom’ created by nesting a number of if statements.

For instance:

guard let quantity = anOptionalInt else {
    return
}

print("anOptionalInt incorporates a worth, and it’s: (quantity)!")

Guards additionally assist the identical neat tips that the if assertion supported, reminiscent of unwrapping a number of optionals on the similar time and utilizing the the place clause.

Whether or not you employ an if or guard assertion fully is determined by whether or not any future code requires the elective to include a worth.

Nil Coalescing Operator

The Nil Coalescing Operator is a nifty shorthand model of the ternary conditional operator, primarily designed to transform optionals to non-optionals. It has the syntax a ?? b, the place a is an elective sort and b is similar sort as a (though often non-optional).

It basically helps you to say “If a incorporates a worth, unwrap it. If it doesn’t then return b as a substitute”. For instance, you could possibly use it like this:

let quantity = anOptionalInt ?? 0

It will outline a quantity fixed of Int sort, that can both include the worth of anOptionalInt, if it incorporates a worth, or 0 in any other case.

It’s simply shorthand for:

let quantity = anOptionalInt != nil ? anOptionalInt! : 0

Non-obligatory Chaining

You need to use Non-obligatory Chaining as a way to name a technique or entry a property on an elective. That is merely executed by suffixing the variable identify with a ? when utilizing it.

For instance, say we have now a variable foo, of sort an elective Foo occasion.

var foo : Foo?

If we wished to name a technique on foo that doesn’t return something, we are able to merely do:

foo?.doSomethingInteresting()

If foo incorporates a worth, this methodology will probably be known as on it. If it doesn’t, nothing dangerous will occur – the code will merely proceed executing.

(That is related behaviour to sending messages to nil in Goal-C)

This will subsequently even be used to set properties in addition to name strategies. For instance:

foo?.bar = Bar()

Once more, nothing dangerous will occur right here if foo is nil. Your code will merely proceed executing.

One other neat trick that elective chaining helps you to do is examine whether or not setting a property or calling a technique was profitable. You are able to do this by evaluating the return worth to nil.

(It’s because an elective worth will return Void? relatively than Void on a technique that doesn’t return something)

For instance:

if (foo?.bar = Bar()) != nil {
    print("bar was set efficiently")
} else {
    print("bar wasn’t set efficiently")
}

Nonetheless, issues turn into a bit bit extra tough when making an attempt to entry properties or name strategies that return a worth. As a result of foo is elective, something returned from it would even be elective. To take care of this, you may both unwrap the optionals that get returned utilizing one of many above strategies – or unwrap foo itself earlier than accessing strategies or calling strategies that return values.

Additionally, because the identify suggests, you may ‘chain’ these statements collectively. Which means if foo has an elective property baz, which has a property qux – you could possibly write the next:

let optionalQux = foo?.baz?.qux

Once more, as a result of foo and baz are elective, the worth returned from qux will at all times be an elective no matter whether or not qux itself is elective.

map and flatMap

An typically underused function with optionals is the power to make use of the map and flatMap capabilities. These can help you apply non-optional transforms to elective variables. If an elective has a worth, you may apply a given transformation to it. If it doesn’t have a worth, it would stay nil.

For instance, let’s say you’ve got an elective string:

let anOptionalString:String?

By making use of the map operate to it – we are able to use the stringByAppendingString operate as a way to concatenate it to a different string.

As a result of stringByAppendingString takes a non-optional string argument, we can’t enter our elective string immediately. Nonetheless, through the use of map, we are able to use permit stringByAppendingString for use if anOptionalString has a worth.

For instance:

var anOptionalString:String? = "bar"

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // Non-obligatory("foobar")

Nonetheless, if anOptionalString doesn’t have a worth, map will return nil. For instance:

var anOptionalString:String?

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // nil

flatMap works equally to map, besides it means that you can return one other elective from throughout the closure physique. This implies you may enter an elective right into a course of that requires a non-optional enter, however can output an elective itself.

strive!

Swift’s error dealing with system could be safely used with Do-Strive-Catch:

do {
    let consequence = strive someThrowingFunc() 
} catch {
    print(error)
}

If someThrowingFunc() throws an error, the error will probably be safely caught within the catch block.

The error fixed you see within the catch block has not been declared by us – it is routinely generated by catch.

It’s also possible to declare error your self, it has the benefit of with the ability to solid it to a helpful format, for instance:

do {
    let consequence = strive someThrowingFunc()    
} catch let error as NSError {
    print(error.debugDescription)
}

Utilizing strive this manner is the right method to strive, catch and deal with errors coming from throwing capabilities.

There’s additionally strive? which absorbs the error:

if let consequence = strive? someThrowingFunc() {
    // cool
} else {
    // deal with the failure, however there is not any error data out there
}

However Swift’s error dealing with system additionally supplies a method to “pressure strive” with strive!:

let consequence = strive! someThrowingFunc()

The ideas defined on this put up additionally apply right here: if an error is thrown, the appliance will crash.

It is best to solely ever use strive! for those who can show that its consequence won’t ever fail in your context – and that is very uncommon.

More often than not you’ll use the whole Do-Strive-Catch system – and the elective one, strive?, within the uncommon instances the place dealing with the error just isn’t essential.


Sources

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments