swift - What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean? -
my swift program crashing exc_bad_instruction
, error. mean, , how fix it?
fatal error: unexpectedly found nil while unwrapping optional value
this post intended collect answers "unexpectedly found nil" issues, not scattered , hard find. feel free add own answer or edit existing wiki answer.
this answer community wiki. if feel made better, feel free edit it!
background: what’s optional?
in swift, optional
generic type can contain value (of kind), or no value @ all.
in many other programming languages, particular "sentinel" value used indicate lack of value. in objective-c, example, nil
(the null pointer) indicates lack of object. gets more tricky when working primitive types — should -1
used indicate absence of integer, or perhaps int_min
, or other integer? if particular value chosen mean "no integer", means can no longer treated valid value.
swift type-safe language, means language helps clear types of values code can work with. if part of code expects string, type safety prevents passing int mistake.
in swift, any type can made optional. optional value can take on value original type, or special value nil
.
optionals defined ?
suffix on type:
var anint: int = 42 var anoptionalint: int? = 42 var anotheroptionalint: int? // `nil` default when no value provided
the lack of value in optional indicated nil
:
anoptionalint = nil
(note nil
not same nil
in objective-c. in objective-c, nil
absence of valid object pointer; in swift, optionals not restricted objects/reference types. optional behaves haskell's maybe.)
why did “fatal error: unexpectedly found nil while unwrapping optional value”?
in order access optional’s value (if has 1 @ all), need unwrap it. optional value can unwrapped safely or forcibly. if force-unwrap optional, , didn't have value, program crash above message.
xcode show crash highlighting line of code. problem occurs on line.
this crash can occur 2 different kinds of force-unwrap:
1. explicit force unwrapping
this done !
operator on optional. example:
let anoptionalstring: string? print(anoptionalstring!) // <- crash
as anoptionalstring
nil
here, crash on line force unwrap it.
2. implicitly unwrapped optionals
these defined !
, rather ?
after type.
var optionaldouble: double! // value implicitly unwrapped wherever it's used
these optionals assumed contain value. therefore whenever access implicitly unwrapped optional, automatically force unwrapped you. if doesn’t contain value, crash.
print(optionaldouble) // <- crash
in order work out variable caused crash, can hold ⌥ while clicking show definition, might find optional type.
iboutlets, in particular, implicitly unwrapped optionals. because xib or storyboard link outlets @ runtime, after initialization. should therefore ensure you’re not accessing outlets before they're loaded in. should check connections correct in storyboard/xib file, otherwise values nil
@ runtime, , therefore crash when implicitly unwrapped.
when should ever force unwrap optional?
explicit force unwrapping
as general rule, should never explicitly force unwrap optional !
operator. there may cases using !
acceptable – should ever using if 100% sure optional contains value.
while there may occasion can use force unwrapping, know fact optional contains value – there not single place cannot safely unwrap optional instead.
implicitly unwrapped optionals
these variables designed can defer assignment until later in code. your responsibility ensure have value before access them. however, because involve force unwrapping, still inherently unsafe – assume value non-nil, though assigning nil valid.
you should using implicitly unwrapped optionals last resort. if can use lazy variable, or provide default value variable – should instead of using implicitly unwrapped optional.
however, there few scenarios implicitly unwrapped optionals beneficial, , still able use various ways of safely unwrapping them listed below – should always use them due caution.
how can safely deal optionals?
the simplest way check whether optional contains value, compare nil
.
if anoptionalint != nil { print("contains value!") } else { print("doesn’t contain value.") }
however, 99.9% of time when working optionals, you’ll want access value contains, if contains 1 @ all. this, can use optional binding.
optional binding
optional binding allows check if optional contains value – , allows assign unwrapped value new variable or constant. uses syntax if let x = anoptional {...}
or if var x = anoptional {...}
, depending if need modify value of new variable after binding it.
for example:
if let number = anoptionalint { print("contains value! \(number)!") } else { print("doesn’t contain number") }
what first check optional contains value. if does, ‘unwrapped’ value assigned new variable (number
) – can freely use if non-optional. if optional doesn’t contain value, else clause invoked, expect.
what’s neat optional binding, can unwrap multiple optionals @ same time. can separate statements comma. statement succeed if optionals unwrapped.
var anoptionalint : int? var anoptionalstring : string? if let number = anoptionalint, text = anoptionalstring { print("anoptionalint contains value: \(number). , anoptionalstring, it’s: \(text)") } else { print("one or more of optionals don’t contain value") }
another neat trick can use where
clause check condition on value, after unwrapping it.
if let number = anoptionalint number > 0 { print("anoptionalint contains value: \(number), , it’s greater zero!") }
the catch using optional binding within if statement, can access unwrapped value within scope of statement. if need access value outside of scope of statement, can use guard statement.
a guard statement allows define condition success – , current scope continue executing if condition met. defined syntax guard condition else {...}
.
so, use them optional binding, can this:
guard let number = anoptionalint else { return }
(note within guard body, must use 1 of control transfer statements in order exit scope of executing code).
if anoptionalint
contains value, unwrapped , assigned new number
constant. code after guard continue executing. if doesn’t contain value – guard execute code within brackets, lead transfer of control, code after not executed.
the real neat thing guard statements unwrapped value available use in code follows statement (as know future code can only execute if optional has value). great eliminating ‘pyramids of doom’ created nesting multiple if statements.
for example:
guard let number = anoptionalint else { return } print("anoptionalint contains value, , it’s: /(number)!")
guards support same neat tricks if statement supported, such unwrapping multiple optionals @ same time , using where
clause.
whether use if or guard statement depends on whether future code requires optional contain value.
nil coalescing operator
the nil coalescing operator nifty shorthand version of ternary conditional operator, designed convert optionals non-optionals. has syntax a ?? b
, a
optional type , b
same type a
(although non-optional).
it lets “if a
contains value, unwrap it. if doesn’t return b
instead”. example, use this:
let number = anoptionalint ?? 0
this define number
constant of int
type, either contain value of anoptionalint
, if contains value, or 0
otherwise.
it’s shorthand for:
let number = anoptionalint != nil ? anoptionalint! : 0
optional chaining
you can use optional chaining in order call method or access property on optional. done suffixing variable name ?
when using it.
for example, have variable foo
, of type optional foo
instance.
var foo : foo?
if wanted call method on foo
doesn’t return anything, can do:
foo?.dosomethinginteresting()
if foo
contains value, method called on it. if doesn’t, nothing bad happen – code continue executing.
(this similar behaviour sending messages nil
in objective-c)
this can therefore used set properties call methods. example:
foo?.bar = bar()
again, nothing bad happen here if foo
nil
. code continue executing.
another neat trick optional chaining lets check whether setting property or calling method successful. can comparing return value nil
.
(this because optional value return void?
rather void
on method doesn’t return anything)
for example:
if (foo?.bar = bar()) != nil { print("bar set successfully") } else { print("bar wasn’t set successfully") }
however, things become little bit more tricky when trying access properties or call methods return value. because foo
optional, returned optional. deal this, can either unwrap optionals returned using 1 of above methods – or unwrap foo
before accessing methods or calling methods return values.
also, name suggests, can ‘chain’ these statements together. means if foo
has optional property baz
, has property qux
– write following:
let optionalqux = foo?.baz?.qux
again, because foo
, baz
optional, value returned qux
optional regardless of whether qux
optional.
map
, flatmap
an underused feature optionals ability use map
, flatmap
functions. these allow apply non-optional transforms optional variables. if optional has value, can apply given transformation it. if doesn’t have value, remain nil
.
for example, let’s have optional string:
let anoptionalstring:string?
by applying map
function – can use stringbyappendingstring
function in order concatenate string.
because stringbyappendingstring
takes non-optional string argument, cannot input our optional string directly. however, using map
, can use allow stringbyappendingstring
used if anoptionalstring
has value.
for example:
var anoptionalstring:string? = "bar" anoptionalstring = anoptionalstring.map {unwrappedstring in return "foo".stringbyappendingstring(unwrappedstring) } print(anoptionalstring) // optional("foobar")
however, if anoptionalstring
doesn’t have value, map
return nil
. example:
var anoptionalstring:string? anoptionalstring = anoptionalstring.map {unwrappedstring in return "foo".stringbyappendingstring(unwrappedstring) } print(anoptionalstring) // nil
flatmap
works map
, except allows return another optional within closure body. means can input optional process requires non-optional input, can output optional itself.
try!
swift's error handling system can safely used do-try-catch:
do { let result = try somethrowingfunc() } catch { print(error) }
if somethrowingfunc()
throws error, error safely caught in catch
block.
the error
constant see in catch
block has not been declared - it's automatically generated catch
.
you can declare error
yourself, has advantage of being able cast useful format, example:
do { let result = try somethrowingfunc() } catch let error nserror { print(error.debugdescription) }
using try
way proper way try, catch , handle errors coming throwing functions.
there's try?
absorbs error:
if let result = try? somethrowingfunc() { // cool } else { // handle failure, there's no error information available }
but swift's error handling system provides way "force try" try!
:
let result = try! somethrowingfunc()
the concepts explained in post apply here: if error thrown, application crash.
you should ever use try!
if can prove result never fail in context - , rare.
most of time use complete do-try-catch system - , optional one, try?
, in rare cases handling error not important.
Comments
Post a Comment