It it okay to access an optional variable with question mark without exclamation mark? - swift

I know that an optional constant or variable with a question mark needs an exclamation mark to access its value. then, I tried to exam it with the following code.
var aaa:String? = "3"
println("aaa = \(aaa!)")
Yes. It was okay. It printed "3" on Console Output. and next exam I tried like that
var aaa:String? = "3"
println("aaa = \(aaa)")
It also printed "3" without any error message. It worked well.
I learned about Forced Unwrapping that en exclamation mark is needed to access to a value of Optional. But, I could access it without the mark. Is it right? I wonder what is wrong. Am I misunderstanding Optional?

You are correctly understanding Optionals and Forced Unwrapping. The reason that you can print the optional variable is that the type Optional can also be printed. If you print an Optional instead of the real value, it will either print the value if it has one, or "nil" if it doesn't.
Also, just in case you don't realize it. Forced Unwrapping will cause the whole program to crash if the optional is nil at the time. To be safer, you should use Optional Binding:
var aaa: String? = "3"
if let actualString = aaa {
// actualString becomes a non-optional version of aaa
// if aaa were nil, this block would not be run at all
println(actualString)
}
Also, some extra information about the printing of instances. Printing uses the protocol Printable which defines a description property. Anything that implements this protocol can customize the way they print out. Optional has its own implementation of this protocol which is how it decides to either print "nil" or the description of the actual value.

Println() will print the value if it has any otherwise it will print nil. Just to understand things better just try to assign value of aaa to another string variable. It will throw error that value of optional type not unwrapped.
var aString:NSString? = "Hello"
var bString = aString // Compiler allows, as you are assigning to optional type again.
var cString:NSString = aString // Compiler throws error. You cannot assign optional type without unwrapping.
So to answer your question you need to use ! to get the value.
Edit:
var foo:Bool?
foo = false
if foo { // This always evaluates to `True`
...
}
if foo! { // This condition will now fail
...
}
The reason foo evaluated to True is because it was not unwrapped. Since its not unwrapped its just checking whether it has a value or not(true or false does not matter).
When foo was unwrapped it returned a value False hence the second if condition failed.

The println function is a special case. It automatically unwraps the variable for you. If the variable were nil, it would print nil. In other contexts, you do need to unwrap the variable yourself.

Related

Is there a proper way to nil-coalescing a string value or handling a nil found while unwrapping an optional error? [duplicate]

My Swift program is crashing with EXC_BAD_INSTRUCTION and one of the following similar errors. What does this error mean, and how do I fix it?
Fatal error: Unexpectedly found nil while unwrapping an Optional value
or
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
This post is intended to collect answers to "unexpectedly found nil" issues, so that they are not scattered and hard to find. Feel free to add your own answer or edit the existing wiki answer.
Background: What’s an Optional?
In Swift, Optional<Wrapped> is an option type: it can contain any value from the original ("Wrapped") type, or no value at all (the special value nil). An optional value must be unwrapped before it can be used.
Optional is a generic type, which means that Optional<Int> and Optional<String> are distinct types — the type inside <> is called the Wrapped type. Under the hood, an Optional is an enum with two cases: .some(Wrapped) and .none, where .none is equivalent to nil.
Optionals can be declared using the named type Optional<T>, or (most commonly) as a shorthand with a ? suffix.
var anInt: Int = 42
var anOptionalInt: Int? = 42
var anotherOptionalInt: Int? // `nil` is the default when no value is provided
var aVerboseOptionalInt: Optional<Int> // equivalent to `Int?`
anOptionalInt = nil // now this variable contains nil instead of an integer
Optionals are a simple yet powerful tool to express your assumptions while writing code. The compiler can use this information to prevent you from making mistakes. From The Swift Programming Language:
Swift is a type-safe language, which means the language helps you to be clear about the types of values your code can work with. If part of your code requires a String, type safety prevents you from passing it an Int by mistake. Likewise, type safety prevents you from accidentally passing an optional String to a piece of code that requires a non-optional String. Type safety helps you catch and fix errors as early as possible in the development process.
Some other programming languages also have generic option types: for example, Maybe in Haskell, option in Rust, and optional in C++17.
In programming languages without option types, a particular "sentinel" value is often used to indicate the absence of a valid value. In Objective-C, for example, nil (the null pointer) represents the lack of an object. For primitive types such as int, a null pointer can't be used, so you would need either a separate variable (such as value: Int and isValid: Bool) or a designated sentinel value (such as -1 or INT_MIN). These approaches are error-prone because it's easy to forget to check isValid or to check for the sentinel value. Also, if a particular value is chosen as the sentinel, that means it can no longer be treated as a valid value.
Option types such as Swift's Optional solve these problems by introducing a special, separate nil value (so you don't have to designate a sentinel value), and by leveraging the strong type system so the compiler can help you remember to check for nil when necessary.
Why did I get “Fatal error: Unexpectedly found nil while unwrapping an Optional value”?
In order to access an optional’s value (if it has one at all), you need to unwrap it. An optional value can be unwrapped safely or forcibly. If you force-unwrap an optional, and it didn't have a value, your program will crash with the above message.
Xcode will show you the crash by highlighting a line of code. The problem occurs on this line.
This crash can occur with two different kinds of force-unwrap:
1. Explicit Force Unwrapping
This is done with the ! operator on an optional. For example:
let anOptionalString: String?
print(anOptionalString!) // <- CRASH
Fatal error: Unexpectedly found nil while unwrapping an Optional value
As anOptionalString is nil here, you will get a crash on the line where you force unwrap it.
2. Implicitly Unwrapped Optionals
These are defined with a !, rather than a ? after the type.
var optionalDouble: Double! // this value is implicitly unwrapped wherever it's used
These optionals are assumed to contain a value. Therefore whenever you access an implicitly unwrapped optional, it will automatically be force unwrapped for you. If it doesn’t contain a value, it will crash.
print(optionalDouble) // <- CRASH
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
In order to work out which variable caused the crash, you can hold ⌥ while clicking to show the definition, where you might find the optional type.
IBOutlets, in particular, are usually implicitly unwrapped optionals. This is because your xib or storyboard will link up the outlets at runtime, after initialization. You should therefore ensure that you’re not accessing outlets before they're loaded in. You also should check that the connections are correct in your storyboard/xib file, otherwise the values will be nil at runtime, and therefore crash when they are implicitly unwrapped. When fixing connections, try deleting the lines of code that define your outlets, then reconnect them.
When should I ever force unwrap an Optional?
Explicit Force Unwrapping
As a general rule, you should never explicitly force unwrap an optional with the ! operator. There may be cases where using ! is acceptable – but you should only ever be using it if you are 100% sure that the optional contains a value.
While there may be an occasion where you can use force unwrapping, as you know for a fact that an optional contains a value – there is not a single place where you cannot safely unwrap that optional instead.
Implicitly Unwrapped Optionals
These variables are designed so that you can defer their assignment until later in your code. It is your responsibility to ensure they have a value before you access them. However, because they involve force unwrapping, they are still inherently unsafe – as they assume your value is non-nil, even though assigning nil is valid.
You should only be using implicitly unwrapped optionals as a last resort. If you can use a lazy variable, or provide a default value for a variable – you should do so instead of using an implicitly unwrapped optional.
However, there are a few scenarios where implicitly unwrapped optionals are beneficial, and you are still able to use various ways of safely unwrapping them as listed below – but you should always use them with due caution.
How can I safely deal with Optionals?
The simplest way to check whether an optional contains a value, is to compare it to nil.
if anOptionalInt != nil {
print("Contains a value!")
} else {
print("Doesn’t contain a value.")
}
However, 99.9% of the time when working with optionals, you’ll actually want to access the value it contains, if it contains one at all. To do this, you can use Optional Binding.
Optional Binding
Optional Binding allows you to check if an optional contains a value – and allows you to assign the unwrapped value to a new variable or constant. It uses the syntax if let x = anOptional {...} or if var x = anOptional {...}, depending if you need to modify the value of the new variable after binding it.
For example:
if let number = anOptionalInt {
print("Contains a value! It is \(number)!")
} else {
print("Doesn’t contain a number")
}
What this does is first check that the optional contains a value. If it does, then the ‘unwrapped’ value is assigned to a new variable (number) – which you can then freely use as if it were non-optional. If the optional doesn’t contain a value, then the else clause will be invoked, as you would expect.
What’s neat about optional binding, is you can unwrap multiple optionals at the same time. You can just separate the statements with a comma. The statement will succeed if all the optionals were unwrapped.
var anOptionalInt : Int?
var anOptionalString : String?
if let number = anOptionalInt, let text = anOptionalString {
print("anOptionalInt contains a value: \(number). And so does anOptionalString, it’s: \(text)")
} else {
print("One or more of the optionals don’t contain a value")
}
Another neat trick is that you can also use commas to check for a certain condition on the value, after unwrapping it.
if let number = anOptionalInt, number > 0 {
print("anOptionalInt contains a value: \(number), and it’s greater than zero!")
}
The only catch with using optional binding within an if statement, is that you can only access the unwrapped value from within the scope of the statement. If you need access to the value from outside of the scope of the statement, you can use a guard statement.
A guard statement allows you to define a condition for success – and the current scope will only continue executing if that condition is met. They are defined with the syntax guard condition else {...}.
So, to use them with an optional binding, you can do this:
guard let number = anOptionalInt else {
return
}
(Note that within the guard body, you must use one of the control transfer statements in order to exit the scope of the currently executing code).
If anOptionalInt contains a value, it will be unwrapped and assigned to the new number constant. The code after the guard will then continue executing. If it doesn’t contain a value – the guard will execute the code within the brackets, which will lead to transfer of control, so that the code immediately after will not be executed.
The real neat thing about guard statements is the unwrapped value is now available to use in code that follows the statement (as we know that future code can only execute if the optional has a value). This is a great for eliminating ‘pyramids of doom’ created by nesting multiple if statements.
For example:
guard let number = anOptionalInt else {
return
}
print("anOptionalInt contains a value, and it’s: \(number)!")
Guards also support the same neat tricks that the if statement supported, such as unwrapping multiple optionals at the same time and using the where clause.
Whether you use an if or guard statement completely depends on whether any future code requires the optional to contain a value.
Nil Coalescing Operator
The Nil Coalescing Operator is a nifty shorthand version of the ternary conditional operator, primarily designed to convert optionals to non-optionals. It has the syntax a ?? b, where a is an optional type and b is the same type as a (although usually non-optional).
It essentially lets you say “If a contains a value, unwrap it. If it doesn’t then return b instead”. For example, you could use it like this:
let number = anOptionalInt ?? 0
This will define a number constant of Int type, that will either contain the value of anOptionalInt, if it contains a value, or 0 otherwise.
It’s just shorthand for:
let number = anOptionalInt != nil ? anOptionalInt! : 0
Optional Chaining
You can use Optional Chaining in order to call a method or access a property on an optional. This is simply done by suffixing the variable name with a ? when using it.
For example, say we have a variable foo, of type an optional Foo instance.
var foo : Foo?
If we wanted to call a method on foo that doesn’t return anything, we can simply do:
foo?.doSomethingInteresting()
If foo contains a value, this method will be called on it. If it doesn’t, nothing bad will happen – the code will simply continue executing.
(This is similar behaviour to sending messages to nil in Objective-C)
This can therefore also be used to set properties as well as call methods. For example:
foo?.bar = Bar()
Again, nothing bad will happen here if foo is nil. Your code will simply continue executing.
Another neat trick that optional chaining lets you do is check whether setting a property or calling a method was successful. You can do this by comparing the return value to nil.
(This is because an optional value will return Void? rather than Void on a method that doesn’t return anything)
For example:
if (foo?.bar = Bar()) != nil {
print("bar was set successfully")
} else {
print("bar wasn’t set successfully")
}
However, things become a little bit more tricky when trying to access properties or call methods that return a value. Because foo is optional, anything returned from it will also be optional. To deal with this, you can either unwrap the optionals that get returned using one of the above methods – or unwrap foo itself before accessing methods or calling methods that return values.
Also, as the name suggests, you can ‘chain’ these statements together. This means that if foo has an optional property baz, which has a property qux – you could write the following:
let optionalQux = foo?.baz?.qux
Again, because foo and baz are optional, the value returned from qux will always be an optional regardless of whether qux itself is optional.
map and flatMap
An often underused feature with optionals is the ability to use the map and flatMap functions. These allow you to apply non-optional transforms to optional variables. If an optional has a value, you can apply a given transformation to it. If it doesn’t have a value, it will remain nil.
For example, let’s say you have an optional string:
let anOptionalString:String?
By applying the map function to it – we can use the stringByAppendingString function in order to concatenate it to another string.
Because stringByAppendingString takes a non-optional string argument, we cannot input our optional string directly. However, by using map, we can use allow stringByAppendingString to be used if anOptionalString has a 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 a value, map will return nil. For example:
var anOptionalString:String?
anOptionalString = anOptionalString.map {unwrappedString in
return "foo".stringByAppendingString(unwrappedString)
}
print(anOptionalString) // nil
flatMap works similarly to map, except it allows you to return another optional from within the closure body. This means you can input an optional into a process that requires a non-optional input, but can output an optional itself.
try!
Swift's error handling system can be safely used with Do-Try-Catch:
do {
let result = try someThrowingFunc()
} catch {
print(error)
}
If someThrowingFunc() throws an error, the error will be safely caught in the catch block.
The error constant you see in the catch block has not been declared by us - it's automatically generated by catch.
You can also declare error yourself, it has the advantage of being able to cast it to a useful format, for example:
do {
let result = try someThrowingFunc()
} catch let error as NSError {
print(error.debugDescription)
}
Using try this way is the proper way to try, catch and handle errors coming from throwing functions.
There's also try? which absorbs the error:
if let result = try? someThrowingFunc() {
// cool
} else {
// handle the failure, but there's no error information available
}
But Swift's error handling system also provides a way to "force try" with try!:
let result = try! someThrowingFunc()
The concepts explained in this post also apply here: if an error is thrown, the application will crash.
You should only ever use try! if you can prove that its result will never fail in your context - and this is very rare.
Most of the time you will use the complete Do-Try-Catch system - and the optional one, try?, in the rare cases where handling the error is not important.
Resources
Apple documentation on Swift Optionals
When to use and when not to use implicitly unwrapped optionals
Learn how to debug an iOS app crash
TL;DR answer
With very few exceptions, this rule is golden:
Avoid use of !
Declare variable optional (?), not implicitly unwrapped optionals (IUO) (!)
In other words, rather use:
var nameOfDaughter: String?
Instead of:
var nameOfDaughter: String!
Unwrap optional variable using if let or guard let
Either unwrap variable like this:
if let nameOfDaughter = nameOfDaughter {
print("My daughters name is: \(nameOfDaughter)")
}
Or like this:
guard let nameOfDaughter = nameOfDaughter else { return }
print("My daughters name is: \(nameOfDaughter)")
This answer was intended to be concise, for full comprehension read accepted answer
Resources
Avoiding force unwrapping
This question comes up ALL THE TIME on SO. It's one of the first things that new Swift developers struggle with.
Background:
Swift uses the concept of "Optionals" to deal with values that could contain a value, or not. In other languages like C, you might store a value of 0 in a variable to indicate that it contains no value. However, what if 0 is a valid value? Then you might use -1. What if -1 is a valid value? And so on.
Swift optionals let you set up a variable of any type to contain either a valid value, or no value.
You put a question mark after the type when you declare a variable to mean (type x, or no value).
An optional is actually a container than contains either a variable of a given type, or nothing.
An optional needs to be "unwrapped" in order to fetch the value inside.
The "!" operator is a "force unwrap" operator. It says "trust me. I know what I am doing. I guarantee that when this code runs, the variable will not contain nil." If you are wrong, you crash.
Unless you really do know what you are doing, avoid the "!" force unwrap operator. It is probably the largest source of crashes for beginning Swift programmers.
How to deal with optionals:
There are lots of other ways of dealing with optionals that are safer. Here are some (not an exhaustive list)
You can use "optional binding" or "if let" to say "if this optional contains a value, save that value into a new, non-optional variable. If the optional does not contain a value, skip the body of this if statement".
Here is an example of optional binding with our foo optional:
if let newFoo = foo //If let is called optional binding. {
print("foo is not nil")
} else {
print("foo is nil")
}
Note that the variable you define when you use optional biding only exists (is only "in scope") in the body of the if statement.
Alternately, you could use a guard statement, which lets you exit your function if the variable is nil:
func aFunc(foo: Int?) {
guard let newFoo = input else { return }
//For the rest of the function newFoo is a non-optional var
}
Guard statements were added in Swift 2. Guard lets you preserve the "golden path" through your code, and avoid ever-increasing levels of nested ifs that sometimes result from using "if let" optional binding.
There is also a construct called the "nil coalescing operator". It takes the form "optional_var ?? replacement_val". It returns a non-optional variable with the same type as the data contained in the optional. If the optional contains nil, it returns the value of the expression after the "??" symbol.
So you could use code like this:
let newFoo = foo ?? "nil" // "??" is the nil coalescing operator
print("foo = \(newFoo)")
You could also use try/catch or guard error handling, but generally one of the other techniques above is cleaner.
EDIT:
Another, slightly more subtle gotcha with optionals is "implicitly unwrapped optionals. When we declare foo, we could say:
var foo: String!
In that case foo is still an optional, but you don't have to unwrap it to reference it. That means any time you try to reference foo, you crash if it's nil.
So this code:
var foo: String!
let upperFoo = foo.capitalizedString
Will crash on reference to foo's capitalizedString property even though we're not force-unwrapping foo. the print looks fine, but it's not.
Thus you want to be really careful with implicitly unwrapped optionals. (and perhaps even avoid them completely until you have a solid understanding of optionals.)
Bottom line: When you are first learning Swift, pretend the "!" character is not part of the language. It's likely to get you into trouble.
Since the above answers clearly explains how to play safely with Optionals.
I will try explain what Optionals are really in swift.
Another way to declare an optional variable is
var i : Optional<Int>
And Optional type is nothing but an enumeration with two cases, i.e
enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
.
.
.
}
So to assign a nil to our variable 'i'. We can do
var i = Optional<Int>.none
or to assign a value, we will pass some value
var i = Optional<Int>.some(28)
According to swift, 'nil' is the absence of value.
And to create an instance initialized with nil We have to conform to a protocol called ExpressibleByNilLiteral and great if you guessed it, only Optionals conform to ExpressibleByNilLiteral and conforming to other types is discouraged.
ExpressibleByNilLiteral has a single method called init(nilLiteral:) which initializes an instace with nil. You usually wont call this method and according to swift documentation it is discouraged to call this initializer directly as the compiler calls it whenever you initialize an Optional type with nil literal.
Even myself has to wrap (no pun intended) my head around Optionals :D
Happy Swfting All.
First, you should know what an Optional value is.
You can step to The Swift Programming Language for detail.
Second, you should know the optional value has two statuses. One is the full value, and the other is a nil value. So before you implement an optional value, you should check which state it is.
You can use if let ... or guard let ... else and so on.
One other way, if you don't want to check the variable state before your implementation, you can also use var buildingName = buildingName ?? "buildingName" instead.
I had this error once when I was trying to set my Outlets values from the prepare for segue method as follows:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DestinationVC{
if let item = sender as? DataItem{
// This line pops up the error
destination.nameLabel.text = item.name
}
}
}
Then I found out that I can't set the values of the destination controller outlets because the controller hasn't been loaded or initialized yet.
So I solved it this way:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DestinationVC{
if let item = sender as? DataItem{
// Created this method in the destination Controller to update its outlets after it's being initialized and loaded
destination.updateView(itemData: item)
}
}
}
Destination Controller:
// This variable to hold the data received to update the Label text after the VIEW DID LOAD
var name = ""
// Outlets
#IBOutlet weak var nameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
nameLabel.text = name
}
func updateView(itemDate: ObjectModel) {
name = itemDate.name
}
I hope this answer helps anyone out there with the same issue as I found the marked answer is great resource to the understanding of optionals and how they work but hasn't addressed the issue itself directly.
Basically you tried to use a nil value in places where Swift allows only non-nil ones, by telling the compiler to trust you that there will never be nil value there, thus allowing your app to compile.
There are several scenarios that lead to this kind of fatal error:
forced unwraps:
let user = someVariable!
If someVariable is nil, then you'll get a crash. By doing a force unwrap you moved the nil check responsibility from the compiler to you, basically by doing a forced unwrap you're guaranteeing to the compiler that you'll never have nil values there. And guess what it happens if somehow a nil value ends in in someVariable?
Solution? Use optional binding (aka if-let), do the variable processing there:
if user = someVariable {
// do your stuff
}
forced (down)casts:
let myRectangle = someShape as! Rectangle
Here by force casting you tell the compiler to no longer worry, as you'll always have a Rectangle instance there. And as long as that holds, you don't have to worry. The problems start when you or your colleagues from the project start circulating non-rectangle values.
Solution? Use optional binding (aka if-let), do the variable processing there:
if let myRectangle = someShape as? Rectangle {
// yay, I have a rectangle
}
Implicitly unwrapped optionals. Let's assume you have the following class definition:
class User {
var name: String!
init() {
name = "(unnamed)"
}
func nicerName() {
return "Mr/Ms " + name
}
}
Now, if no-one messes up with the name property by setting it to nil, then it works as expected, however if User is initialized from a JSON that lacks the name key, then you get the fatal error when trying to use the property.
Solution? Don't use them :) Unless you're 102% sure that the property will always have a non-nil value by the time it needs to be used. In most cases converting to an optional or non-optional will work. Making it non-optional will also result in the compiler helping you by telling the code paths you missed giving a value to that property
Unconnected, or not yet connected, outlets. This is a particular case of scenario #3. Basically you have some XIB-loaded class that you want to use.
class SignInViewController: UIViewController {
#IBOutlet var emailTextField: UITextField!
}
Now if you missed connecting the outlet from the XIB editor, then the app will crash as soon as you'll want to use the outlet.
Solution? Make sure all outlets are connected. Or use the ? operator on them: emailTextField?.text = "my#email.com". Or declare the outlet as optional, though in this case the compiler will force you to unwrap it all over the code.
Values coming from Objective-C, and that don't have nullability annotations. Let's assume we have the following Objective-C class:
#interface MyUser: NSObject
#property NSString *name;
#end
Now if no nullability annotations are specified (either explicitly or via NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END), then the name property will be imported in Swift as String! (an IUO - implicitly unwrapped optional). As soon as some swift code will want to use the value, it will crash if name is nil.
Solution? Add nullability annotations to your Objective-C code. Beware though, the Objective-C compiler is a little bit permissive when it comes to nullability, you might end up with nil values, even if you explicitly marked them as nonnull.
This is more of a important comment and that why implicitly unwrapped optionals can be deceptive when it comes to debugging nil values.
Think of the following code:
It compiles with no errors/warnings:
c1.address.city = c3.address.city
Yet at runtime it gives the following error: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Can you tell me which object is nil?
You can't!
The full code would be:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var c1 = NormalContact()
let c3 = BadContact()
c1.address.city = c3.address.city // compiler hides the truth from you and then you sudden get a crash
}
}
struct NormalContact {
var address : Address = Address(city: "defaultCity")
}
struct BadContact {
var address : Address!
}
struct Address {
var city : String
}
Long story short by using var address : Address! you're hiding the possibility that a variable can be nil from other readers. And when it crashes you're like "what the hell?! my address isn't an optional, so why am I crashing?!.
Hence it's better to write as such:
c1.address.city = c2.address!.city // ERROR: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Can you now tell me which object it is that was nil?
This time the code has been made more clear to you. You can rationalize and think that likely it's the address parameter that was forcefully unwrapped.
The full code would be :
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var c1 = NormalContact()
let c2 = GoodContact()
c1.address.city = c2.address!.city
c1.address.city = c2.address?.city // not compile-able. No deceiving by the compiler
c1.address.city = c2.address.city // not compile-able. No deceiving by the compiler
if let city = c2.address?.city { // safest approach. But that's not what I'm talking about here.
c1.address.city = city
}
}
}
struct NormalContact {
var address : Address = Address(city: "defaultCity")
}
struct GoodContact {
var address : Address?
}
struct Address {
var city : String
}
The errors EXC_BAD_INSTRUCTION and fatal error: unexpectedly found nil while implicitly unwrapping an Optional value appears the most when you have declared an #IBOutlet, but not connected to the storyboard.
You should also learn about how Optionals work, mentioned in other answers, but this is the only time that mostly appears to me.
If you get this error in CollectionView try to create CustomCell file and Custom xib also.
add this code in ViewDidLoad() at mainVC.
let nib = UINib(nibName: "CustomnibName", bundle: nil)
self.collectionView.register(nib, forCellWithReuseIdentifier: "cell")
Xcode 12 iOS 14 Swift 5
My problem was the type of navigation as I called the vie controller direct without instantiating the storyboard so that's mean data was not set yet from the storyboard.
When you navigate, navigate with
let homeViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "home") as? HomeEventsViewController
homeViewController?.modalTransitionStyle = .crossDissolve
homeViewController?.modalPresentationStyle = .fullScreen
view.present(homeViewController ?? UIViewController(), animated: true, completion: nil)
Hopefully it works :-)
I came across this error while making a segue from a table view controller to a view controller because I had forgotten to specify the custom class name for the view controller in the main storyboard.
Something simple that is worth checking if all else looks ok
If my case I set a variable to UILabel which was nil.
So I fixed it and thereafter it did not throw the error.
Code snippet
class ResultViewController: UIViewController {
#IBOutlet weak var resultLabel: UILabel!
var bmiValue=""
override func viewDidLoad() {
super.viewDidLoad()
print(bmiValue)
resultLabel.text=bmiValue //where bmiValue was nil , I fixed it and problem was solved
}
#IBAction func recaculateBmi(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
}
in simple words
you are trying to use a value of the optional variable which is nil.
quick fix could be use guard or if let instead of force unwrap like putting ! at the end of variable
Swift 5.7 +
if let shorthand for shadowing an existing optional variable
Above answers clearly explains why this issue arises and how to handle this issue. But there is a new way of handling this issue from swift 5.7+ onwards.
var myVariable : Int?
Previously
if let myVariable = myVariable {
//this part get executed if the variable is not nil
}else{
//this part get executed if the variable is nil
}
now
here now we can omit the right hand side of the expression.
if let myVariable {
//this part get executed if the variable is not nil
}else{
//this part get executed if the variable is nil
}
Previously we had to repeat the referenced identifier twice, which can cause these optional binding conditions to be verbose, especially when using lengthy variable names.
But now there is a shorthand syntax for optional binding by omitting the right hand side of the expression.
Same thing is applicable for guard let statement.
For more details :
Proposal for if-let shorthand
This is because you are trying to use a value which can possible be nil, but you decided you don't want to have to check it, but instead assume its set when you uses it and define it as !, there are different philosophies on use of variable set as force unwrap, some people are against there use at all, I personal think they are ok for things that will crash all the time and are simple to reason about, usually references to resource, like outlets to xib files, or uses of images with you app that are part of your assets, if these are not set up properly, you app is going to crash straight away, for a very obvious reason, you can get into difficult when the order of objects being created can be uncertain, and trying to reason solutions to this can be difficult, it usually means a bad design as even it you make them optional, calls to you optional variable may not ever be executed, some projects can demand use of force unwraps for security reasons, things like banking apps, because they want the app to crash rather then continue to work in an unplanned way.

what is the difference between "?" and "!" operator in swift?

I was just wondering what is the difference between "?" and "!" in swift, I'm new to swift. I tried looking for questions similar in here, but couldn't find any.
An optional type can be nil
var nameOfToy: String?
The toy may have a name;
nameOfToy = "Buzz"
so
print (nameOfToy!)
is Buzz.
The question mark indicates that it is optional, i.e. can be nil, so you have to UNWRAP it with the !. This is because the variable is optional.
But what happens if there is no name of a toy, and you use !. In this case you get a nasty crash.
These characters have different meanings depending on the context. More than likely you are referring to their uses in unwrapping optionals.
If you have a variable foo:
var foo: Int?
You have declared the variable as an Optional. An Optional is a variable that can contain some value, or no value (nil.) Think of an Optional as a box, or wrapper, around another data type. In order to get at the value inside the optional, you have to unwrap it.
The question mark is the unwrap operator.
Say you have a more complex object like a struct:
struct Foo {
bar: Int
}
var aFoo: Foo?
You've created an Optional instance of Foo called aFoo. The variable aFoo either contains a Foo object, or it contains nil.
You could use code like this:
if aFoo?.bar == 3 {
print("aFoo contains an int == 3")
} else {
print("aFoo is either nil or contains some other value")
}
The ! operator is the "force unwrap" operator. I call it the "crash if nil" operator. If you rewrite the code above using force-unwap:
if aFoo!.bar == 3 {
print("aFoo contains an int == 3")
}
Then there is no point in having an else clause, since if aFoo is nil, you are guaranteed to crash.
You should only use the force-unwrap operator if you are certain that the Optional is not nil.
Optionals are a very important concept in Swift, so you should study them, and the various ways to handle them, until it's second nature.
Make sure you learn about "optional chaining", "optional binding", the nil coalescing operator, guard statements, and force unwrapping, to name a few techniques to deal with optionals.
“To declare an optional, we just have to add a question mark after the type’s name.To read the value of an optional, we have to unwrap it by adding an exclamation mark at the end of the name.”
“Declaring implicitly unwrapped optionals”
“Swift provides the possibility to declare implicitly unwrapped optionals. These are optional variables declared with the exclamation mark instead of the question mark. The system reads these variables as optionals until they are assigned a value and therefore we don’t have to unwrap them anymore.”
var mynumber: Int!
mynumber = 5
var total = mynumber * 10  // 50

Swift string vs. string! vs. string?

I have read this question and some other questions. But they are somewhat unrelated to my question
For UILabel if you don't specify ? or ! you will get such an error:
#IBOutlet property has non-optional type 'UILabel'
Which then Xcode gives you 2 choices to have it fixed, you can do:
fix-it Add ? to form the optional type UIlabel?
fix-it Add ! to form
the implicitly unwrapped optional type UIlabel?
However for string you can just type string without ? or ! and you won't get an error why is that?
What happens if the name isn't set? Then we would have a nil isn't using ?, ! and Swift all about satisfying 'type-safety'?
Example:
struct PancakeHouse {
let name: String // this doesn't have '?' nor '!'
let photo: UIImage?
let location: CLLocationCoordinate2D?
let details: String
}
My major confussion is when would we want to not use Optional?
All this is covered in the documentation: The Swift Programming Language - The Basics.
In short:
String represents a String that's guaranteed to be present. There is no way this value can be nil, thus it's safe to use directly.
String? represents a Optional<String>, which can be nil. You can't use it directly, you must first unwrap it (using a guard, if let, or the force unwrap operator !) to produce a String. As long as you don't force unwrap it with !, this too is safe.
String! also represents an Optional<String>, which can be nil. However, this optional can be used where non-optionals are expected, which causes implicit forced unwrapping. It's like having a String? and having it always be implicitly force unwrapped with !. These are dangerous, as an occurrence of nil will crash your program (unless you check for nil manually).
For your PancakeHouse struct, name is non-optional. That means that its name property cannot be nil. The compiler will enforce a requirement that name be initialized to a non-nil value anytime an instance of PancakeHouse is initialized. It does this by requiring name to be set in any and all initializers defined for PancakeHouse.
For #IBOutlet properties, this is not possible. When an Interface Builder file (XIB or Storyboard) is unarchived/loaded, the outlets defined in the IB file are set, but this always occurs after the objects therein have been initialized (e.g. during view loading). So there is necessarily a time after initialization but before the outlets have been set, and during this time, the outlets will be nil. (There's also the issue that the outlets may not be set in the IB file, and the compiler doesn't/can't check that.) This explains why #IBOutlet properties must be optional.
The choice between an implicitly unwrapped optional (!) and a regular optional (?) for #IBOutlets is up to you. The arguments are essentially that using ! lets you treat the property as if it were non-optional and therefore never nil. If they are nil for some reason, that would generally be considered a programmer error (e.g. outlet is not connected, or you accessed it before view loading finished, etc.), and in those cases, failing by crashing during development will help you catch the bug faster. On the other hand, declaring them as regular optionals, requires any code that uses them to explicitly handle the case where they may not be set for some reason. Apple chose implicitly unwrapped as the default, but there are Swift programmers who for their own reasons, use regular optionals for #IBOutlet properties.
The whole "optional" thing messed with me bad at first. What made it "click" for me, was when I stopped thinking of those as "String" objects and started thinking of them as generics. Just like "Array" with generic identifier for "String" is an array that, if it has values, contains strings... "String?" is an Optional that, if it has a value, is a string.
String - This is always guaranteed to be some kind of string, and NEVER nil. When you declare a variable, it must be given a value.
String? - This is an optional. It can be nil, and IF it has a value, it will be a string. In order to access the optional's value, you must unwrap it.
String! - This is an optional, with syntax sugar that lets you access its value directly as if it where just a String. It COULD be nil, but for whatever reason, the context around the variable has winked at you and said "don't worry, it will have a value."
Thanks to Andrew Madsen's answer and all other answers, I learnt a bit myself:
struct pairOfOptionalAndNonOptionalAndImplicitUnwrapped{
var word1 :String?
var word2 :String
var word3: String!
init (a:String, b: String, c: String){
self.word1 = a // Line A
self.word2 = b // Line B
self.word3 = c // Line C
} //Line BBBB
func equal() ->Bool{
return word1 == word2 + word3
}
}
let wordParts = pairOfOptionalAndNonOptionalAndImplicitUnwrapped (a:"partTwo", b: "part", c:"Two")
wordParts.equal() // Line CCCC
If I comment out Line A only, I will get no errors, because it is optional, and optionals can be set to nil.
If I comment out Line B only, I will get a compilation error on Line BBBB, saying: Return from initializer without initializing all stored properties, I get this because I have declared property word2 as non-optional. I have told the compiler I have guaranteed to have you set...
If I comment out Line C only, I will not get an error, unless I actually run a method on my object. The error you could get is: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0) if and only if I run wordParts.equal(), because I told my code that it's an optional meaning that it will be set from elsewhere after instantiation/compilation. Meaning that lldb can through me a runtime error if you it didn't get set. ( the error would happen on line CCCC)

little confuse about optionals in swift

Maybe I'm very confused idk yet. I thought i understood the basic concept but when playing around in xcode I'm not getting what I thought I should be
Take the following code
var title: String? = "hello world"
println("\(title)")
I thought that this would give me an error because I thought that title should have to be unwrapped since I;m accessing it, but it seems to compile just fine. Can someone shed some light on this.
Optionals are Printables, meaning you can print them to an output stream (here the console). You should see something like Optional("hello world") in your console and not hello world
All an optional is is that if it is nil, the app won't crash. If you put the elimination mark, and did not assign a value, it would crash.
In an if statement, you can check if the variable is nil:
if (title == nil) {
//this works
}
As per documentation, your statement will be converted to
var title: Optional<String> = Some("hello world").
From Apple documentation, Optional is
enum Optional<A> {
case Nil
case Some(A)
}
So when you are passing a value to an optional, at the time of declaration, compiler understands, it has got a value and that's why it is not showing error.
But if you do the below code you may get different result.
var title: String? = "hello world"
title = nil
println("\(title)")
It will print "nil" in playground.
Based on apple doc
The concept of optionals doesn’t exist in C or Objective-C. The
nearest thing in Objective-C is the ability to return nil from a
method that would otherwise return an object, with nil meaning “the
absence of a valid object.” However, this only works for objects—it
doesn’t work for structures, basic C types, or enumeration values. For
these types, Objective-C methods typically return a special value
(such as NSNotFound) to indicate the absence of a value. This approach
assumes that the method’s caller knows there is a special value to
test against and remembers to check for it. Swift’s optionals let you
indicate the absence of a value for any type at all, without the need
for special constants.
Example
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark
Reference: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
var title: String? = "hello world"
println("\(title)") // This would print out Optional(Title)
var title2: String! = "hello world"
println("\(title2)") // This would print in Title
Optional do not cause your program to crash when they are executed without a value but !(variable) will cause your code to crash if they have no value.
Swift documentation:
As described above, optionals indicate that a constant or variable is allowed to have “no value”. Optionals can be checked with an if statement to see if a value exists, and can be conditionally unwrapped with optional binding to access the optional’s value if it does exist.

What is an optional value in Swift?

From Apple's documentation:
You can use if and let together to work with values that might be missing. These values are represented as optionals. An optional value either contains a value or contains nil to indicate that the value is missing. Write a question mark (?) after the type of a value to mark the value as optional.
Why would you want to use an optional value?
An optional in Swift is a type that can hold either a value or no value. Optionals are written by appending a ? to any type:
var name: String? = "Bertie"
Optionals (along with Generics) are one of the most difficult Swift concepts to understand. Because of how they are written and used, it's easy to get a wrong idea of what they are. Compare the optional above to creating a normal String:
var name: String = "Bertie" // No "?" after String
From the syntax it looks like an optional String is very similar to an ordinary String. It's not. An optional String is not a String with some "optional" setting turned on. It's not a special variety of String. A String and an optional String are completely different types.
Here's the most important thing to know: An optional is a kind of container. An optional String is a container which might contain a String. An optional Int is a container which might contain an Int. Think of an optional as a kind of parcel. Before you open it (or "unwrap" in the language of optionals) you won't know if it contains something or nothing.
You can see how optionals are implemented in the Swift Standard Library by typing "Optional" into any Swift file and ⌘-clicking on it. Here's the important part of the definition:
enum Optional<Wrapped> {
case none
case some(Wrapped)
}
Optional is just an enum which can be one of two cases: .none or .some. If it's .some, there's an associated value which, in the example above, would be the String "Hello". An optional uses Generics to give a type to the associated value. The type of an optional String isn't String, it's Optional, or more precisely Optional<String>.
Everything Swift does with optionals is magic to make reading and writing code more fluent. Unfortunately this obscures the way it actually works. I'll go through some of the tricks later.
Note: I'll be talking about optional variables a lot, but it's fine to create optional constants too. I mark all variables with their type to make it easier to understand type types being created, but you don't have to in your own code.
How to create optionals
To create an optional, append a ? after the type you wish to wrap. Any type can be optional, even your own custom types. You can't have a space between the type and the ?.
var name: String? = "Bob" // Create an optional String that contains "Bob"
var peter: Person? = Person() // An optional "Person" (custom type)
// A class with a String and an optional String property
class Car {
var modelName: String // must exist
var internalName: String? // may or may not exist
}
Using optionals
You can compare an optional to nil to see if it has a value:
var name: String? = "Bob"
name = nil // Set name to nil, the absence of a value
if name != nil {
print("There is a name")
}
if name == nil { // Could also use an "else"
print("Name has no value")
}
This is a little confusing. It implies that an optional is either one thing or another. It's either nil or it's "Bob". This is not true, the optional doesn't transform into something else. Comparing it to nil is a trick to make easier-to-read code. If an optional equals nil, this just means that the enum is currently set to .none.
Only optionals can be nil
If you try to set a non-optional variable to nil, you'll get an error.
var red: String = "Red"
red = nil // error: nil cannot be assigned to type 'String'
Another way of looking at optionals is as a complement to normal Swift variables. They are a counterpart to a variable which is guaranteed to have a value. Swift is a careful language that hates ambiguity. Most variables are define as non-optionals, but sometimes this isn't possible. For example, imagine a view controller which loads an image either from a cache or from the network. It may or may not have that image at the time the view controller is created. There's no way to guarantee the value for the image variable. In this case you would have to make it optional. It starts as nil and when the image is retrieved, the optional gets a value.
Using an optional reveals the programmers intent. Compared to Objective-C, where any object could be nil, Swift needs you to be clear about when a value can be missing and when it's guaranteed to exist.
To use an optional, you "unwrap" it
An optional String cannot be used in place of an actual String. To use the wrapped value inside an optional, you have to unwrap it. The simplest way to unwrap an optional is to add a ! after the optional name. This is called "force unwrapping". It returns the value inside the optional (as the original type) but if the optional is nil, it causes a runtime crash. Before unwrapping you should be sure there's a value.
var name: String? = "Bob"
let unwrappedName: String = name!
print("Unwrapped name: \(unwrappedName)")
name = nil
let nilName: String = name! // Runtime crash. Unexpected nil.
Checking and using an optional
Because you should always check for nil before unwrapping and using an optional, this is a common pattern:
var mealPreference: String? = "Vegetarian"
if mealPreference != nil {
let unwrappedMealPreference: String = mealPreference!
print("Meal: \(unwrappedMealPreference)") // or do something useful
}
In this pattern you check that a value is present, then when you are sure it is, you force unwrap it into a temporary constant to use. Because this is such a common thing to do, Swift offers a shortcut using "if let". This is called "optional binding".
var mealPreference: String? = "Vegetarian"
if let unwrappedMealPreference: String = mealPreference {
print("Meal: \(unwrappedMealPreference)")
}
This creates a temporary constant (or variable if you replace let with var) whose scope is only within the if's braces. Because having to use a name like "unwrappedMealPreference" or "realMealPreference" is a burden, Swift allows you to reuse the original variable name, creating a temporary one within the bracket scope
var mealPreference: String? = "Vegetarian"
if let mealPreference: String = mealPreference {
print("Meal: \(mealPreference)") // separate from the other mealPreference
}
Here's some code to demonstrate that a different variable is used:
var mealPreference: String? = "Vegetarian"
if var mealPreference: String = mealPreference {
print("Meal: \(mealPreference)") // mealPreference is a String, not a String?
mealPreference = "Beef" // No effect on original
}
// This is the original mealPreference
print("Meal: \(mealPreference)") // Prints "Meal: Optional("Vegetarian")"
Optional binding works by checking to see if the optional equals nil. If it doesn't, it unwraps the optional into the provided constant and executes the block. In Xcode 8.3 and later (Swift 3.1), trying to print an optional like this will cause a useless warning. Use the optional's debugDescription to silence it:
print("\(mealPreference.debugDescription)")
What are optionals for?
Optionals have two use cases:
Things that can fail (I was expecting something but I got nothing)
Things that are nothing now but might be something later (and vice-versa)
Some concrete examples:
A property which can be there or not there, like middleName or spouse in a Person class
A method which can return a value or nothing, like searching for a match in an array
A method which can return either a result or get an error and return nothing, like trying to read a file's contents (which normally returns the file's data) but the file doesn't exist
Delegate properties, which don't always have to be set and are generally set after initialization
For weak properties in classes. The thing they point to can be set to nil at any time
A large resource that might have to be released to reclaim memory
When you need a way to know when a value has been set (data not yet loaded > the data) instead of using a separate dataLoaded Boolean
Optionals don't exist in Objective-C but there is an equivalent concept, returning nil. Methods that can return an object can return nil instead. This is taken to mean "the absence of a valid object" and is often used to say that something went wrong. It only works with Objective-C objects, not with primitives or basic C-types (enums, structs). Objective-C often had specialized types to represent the absence of these values (NSNotFound which is really NSIntegerMax, kCLLocationCoordinate2DInvalid to represent an invalid coordinate, -1 or some negative value are also used). The coder has to know about these special values so they must be documented and learned for each case. If a method can't take nil as a parameter, this has to be documented. In Objective-C, nil was a pointer just as all objects were defined as pointers, but nil pointed to a specific (zero) address. In Swift, nil is a literal which means the absence of a certain type.
Comparing to nil
You used to be able to use any optional as a Boolean:
let leatherTrim: CarExtras? = nil
if leatherTrim {
price = price + 1000
}
In more recent versions of Swift you have to use leatherTrim != nil. Why is this? The problem is that a Boolean can be wrapped in an optional. If you have Boolean like this:
var ambiguous: Boolean? = false
it has two kinds of "false", one where there is no value and one where it has a value but the value is false. Swift hates ambiguity so now you must always check an optional against nil.
You might wonder what the point of an optional Boolean is? As with other optionals the .none state could indicate that the value is as-yet unknown. There might be something on the other end of a network call which takes some time to poll. Optional Booleans are also called "Three-Value Booleans"
Swift tricks
Swift uses some tricks to allow optionals to work. Consider these three lines of ordinary looking optional code;
var religiousAffiliation: String? = "Rastafarian"
religiousAffiliation = nil
if religiousAffiliation != nil { ... }
None of these lines should compile.
The first line sets an optional String using a String literal, two different types. Even if this was a String the types are different
The second line sets an optional String to nil, two different types
The third line compares an optional string to nil, two different types
I'll go through some of the implementation details of optionals that allow these lines to work.
Creating an optional
Using ? to create an optional is syntactic sugar, enabled by the Swift compiler. If you want to do it the long way, you can create an optional like this:
var name: Optional<String> = Optional("Bob")
This calls Optional's first initializer, public init(_ some: Wrapped), which infers the optional's associated type from the type used within the parentheses.
The even longer way of creating and setting an optional:
var serialNumber:String? = Optional.none
serialNumber = Optional.some("1234")
print("\(serialNumber.debugDescription)")
Setting an optional to nil
You can create an optional with no initial value, or create one with the initial value of nil (both have the same outcome).
var name: String?
var name: String? = nil
Allowing optionals to equal nil is enabled by the protocol ExpressibleByNilLiteral (previously named NilLiteralConvertible). The optional is created with Optional's second initializer, public init(nilLiteral: ()). The docs say that you shouldn't use ExpressibleByNilLiteral for anything except optionals, since that would change the meaning of nil in your code, but it's possible to do it:
class Clint: ExpressibleByNilLiteral {
var name: String?
required init(nilLiteral: ()) {
name = "The Man with No Name"
}
}
let clint: Clint = nil // Would normally give an error
print("\(clint.name)")
The same protocol allows you to set an already-created optional to nil. Although it's not recommended, you can use the nil literal initializer directly:
var name: Optional<String> = Optional(nilLiteral: ())
Comparing an optional to nil
Optionals define two special "==" and "!=" operators, which you can see in the Optional definition. The first == allows you to check if any optional is equal to nil. Two different optionals which are set to .none will always be equal if the associated types are the same. When you compare to nil, behind the scenes Swift creates an optional of the same associated type, set to .none then uses that for the comparison.
// How Swift actually compares to nil
var tuxedoRequired: String? = nil
let temp: Optional<String> = Optional.none
if tuxedoRequired == temp { // equivalent to if tuxedoRequired == nil
print("tuxedoRequired is nil")
}
The second == operator allows you to compare two optionals. Both have to be the same type and that type needs to conform to Equatable (the protocol which allows comparing things with the regular "==" operator). Swift (presumably) unwraps the two values and compares them directly. It also handles the case where one or both of the optionals are .none. Note the distinction between comparing to the nil literal.
Furthermore, it allows you to compare any Equatable type to an optional wrapping that type:
let numberToFind: Int = 23
let numberFromString: Int? = Int("23") // Optional(23)
if numberToFind == numberFromString {
print("It's a match!") // Prints "It's a match!"
}
Behind the scenes, Swift wraps the non-optional as an optional before the comparison. It works with literals too (if 23 == numberFromString {)
I said there are two == operators, but there's actually a third which allow you to put nil on the left-hand side of the comparison
if nil == name { ... }
Naming Optionals
There is no Swift convention for naming optional types differently from non-optional types. People avoid adding something to the name to show that it's an optional (like "optionalMiddleName", or "possibleNumberAsString") and let the declaration show that it's an optional type. This gets difficult when you want to name something to hold the value from an optional. The name "middleName" implies that it's a String type, so when you extract the String value from it, you can often end up with names like "actualMiddleName" or "unwrappedMiddleName" or "realMiddleName". Use optional binding and reuse the variable name to get around this.
The official definition
From "The Basics" in the Swift Programming Language:
Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Optionals are similar to using nil with pointers in Objective-C, but they work for any type, not just classes. Optionals are safer and more expressive than nil pointers in Objective-C and are at the heart of many of Swift’s most powerful features.
Optionals are an example of the fact that Swift is a type safe language. Swift helps you to be clear about the types of values your code can work with. If part of your code expects a String, type safety prevents you from passing it an Int by mistake. This enables you to catch and fix errors as early as possible in the development process.
To finish, here's a poem from 1899 about optionals:
Yesterday upon the stair
I met a man who wasn’t there
He wasn’t there again today
I wish, I wish he’d go away
Antigonish
More resources:
The Swift Programming Guide
Optionals in Swift (Medium)
WWDC Session 402 "Introduction to Swift" (starts around 14:15)
More optional tips and tricks
Let's take the example of an NSError, if there isn't an error being returned you'd want to make it optional to return Nil. There's no point in assigning a value to it if there isn't an error..
var error: NSError? = nil
This also allows you to have a default value. So you can set a method a default value if the function isn't passed anything
func doesntEnterNumber(x: Int? = 5) -> Bool {
if (x == 5){
return true
} else {
return false
}
}
You can't have a variable that points to nil in Swift — there are no pointers, and no null pointers. But in an API, you often want to be able to indicate either a specific kind of value, or a lack of value — e.g. does my window have a delegate, and if so, who is it? Optionals are Swift's type-safe, memory-safe way to do this.
I made a short answer, that sums up most of the above, to clean the uncertainty that was in my head as a beginner:
Opposed to Objective-C, no variable can contain nil in Swift, so the Optional variable type was added (variables suffixed by "?"):
var aString = nil //error
The big difference is that the Optional variables don't directly store values (as a normal Obj-C variables would) they contain two states: "has a value" or "has nil":
var aString: String? = "Hello, World!"
aString = nil //correct, now it contains the state "has nil"
That being, you can check those variables in different situations:
if let myString = aString? {
println(myString)
}
else {
println("It's nil") // this will print in our case
}
By using the "!" suffix, you can also access the values wrapped in them, only if those exist. (i.e it is not nil):
let aString: String? = "Hello, World!"
// var anotherString: String = aString //error
var anotherString: String = aString!
println(anotherString) //it will print "Hello, World!"
That's why you need to use "?" and "!" and not use all of them by default. (this was my biggest bewilderment)
I also agree with the answer above: Optional type cannot be used as a boolean.
In objective C variables with no value were equal to 'nil'(it was also possible to use 'nil' values same as 0 and false), hence it was possible to use variables in conditional statements (Variables having values are same as 'TRUE' and those with no values were equal to 'FALSE').
Swift provides type safety by providing 'optional value'. i.e. It prevents errors formed from assigning variables of different types.
So in Swift, only booleans can be provided on conditional statements.
var hw = "Hello World"
Here, even-though 'hw' is a string, it can't be used in an if statement like in objective C.
//This is an error
if hw
{..}
For that it needs to be created as,
var nhw : String? = "Hello World"
//This is correct
if nhw
{..}
Optional value allows you to show absence of value. Little bit like NULL in SQL or NSNull in Objective-C. I guess this will be an improvement as you can use this even for "primitive" types.
// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/gb/jEUH0.l
An optional means that Swift is not entirely sure if the value corresponds to the type: for example, Int? means that Swift is not entirely sure whether the number is an Int.
To remove it, there are three methods you could employ.
1) If you are absolutely sure of the type, you can use an exclamation mark to force unwrap it, like this:
// Here is an optional variable:
var age: Int?
// Here is how you would force unwrap it:
var unwrappedAge = age!
If you do force unwrap an optional and it is equal to nil, you may encounter this crash error:
This is not necessarily safe, so here's a method that might prevent crashing in case you are not certain of the type and value:
Methods 2 and three safeguard against this problem.
2) The Implicitly Unwrapped Optional
if let unwrappedAge = age {
// continue in here
}
Note that the unwrapped type is now Int, rather than Int?.
3) The guard statement
guard let unwrappedAge = age else {
// continue in here
}
From here, you can go ahead and use the unwrapped variable. Make sure only to force unwrap (with an !), if you are sure of the type of the variable.
Good luck with your project!
When i started to learn Swift it was very difficult to realize why optional.
Lets think in this way.
Let consider a class Person which has two property name and company.
class Person: NSObject {
var name : String //Person must have a value so its no marked as optional
var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible
init(name:String,company:String?) {
self.name = name
self.companyName = company
}
}
Now lets create few objects of Person
var tom:Person = Person.init(name: "Tom", company: "Apple")//posible
var bob:Person = Person.init(name: "Bob", company:nil) // also Possible because company is marked as optional so we can give Nil
But we can not pass Nil to name
var personWithNoName:Person = Person.init(name: nil, company: nil)
Now Lets talk about why we use optional?.
Lets consider a situation where we want to add Inc after company name like apple will be apple Inc. We need to append Inc after company name and print.
print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.
Now lets study why optional takes into place.
if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
print(companyString+" Inc") //Will never executed and no crash!!!
}
Lets replace bob with tom
if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
print(companyString+" Inc") //Will executed and no crash!!!
}
And Congratulation! we have properly deal with optional?
So the realization points are
We will mark a variable as optional if its possible to be nil
If we want to use this variable somewhere in code compiler will
remind you that we need to check if we have proper deal with that variable
if it contain nil.
Thank you...Happy Coding
Lets Experiment with below code Playground.I Hope will clear idea what is optional and reason of using it.
var sampleString: String? ///Optional, Possible to be nil
sampleString = nil ////perfactly valid as its optional
sampleString = "some value" //Will hold the value
if let value = sampleString{ /// the sampleString is placed into value with auto force upwraped.
print(value+value) ////Sample String merged into Two
}
sampleString = nil // value is nil and the
if let value = sampleString{
print(value + value) ///Will Not execute and safe for nil checking
}
// print(sampleString! + sampleString!) //this line Will crash as + operator can not add nil
From https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html:
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
To understand deeper, read the link above.
Well...
? (Optional) indicates your variable may contain a nil value while ! (unwrapper) indicates your variable must have a memory (or value) when it is used (tried to get a value from it) at runtime.
The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.
To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a nonoptional value. You can use this optional return value to check whether the optional chaining call was successful (the returned optional contains a value), or did not succeed due to a nil value in the chain (the returned optional value is nil).
Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int will return an Int? when accessed through optional chaining.
var defaultNil : Int? // declared variable with default nil value
println(defaultNil) >> nil
var canBeNil : Int? = 4
println(canBeNil) >> optional(4)
canBeNil = nil
println(canBeNil) >> nil
println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper
var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4
var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it's not optional and show a compile time error
Here is basic tutorial in detail, by Apple Developer Committee: Optional Chaining
An optional in Swift is a type that can hold either a value or no value. Optionals are written by appending a ? to any type:
var name: String?
You can refer to this link to get knowledge in deep: https://medium.com/#agoiabeladeyemi/optionals-in-swift-2b141f12f870
There are lots of errors which are caused by people trying to use a value which is not set, sometime this can cause a crash, in objective c trying to call the methods of a nil object reference would just be ignored, so some piece of your code not executing and the compiler or written code has no way of telling your why. An optional argument let you have variables that can never be nil, and if you try to do build it the compiler can tell you before your code has even had a chance to run, or you can decide that its appropriate for the object to be undefined, and then the compiler can tell you when you try to write something that doesn't take this into account.
In the case of calling a possible nil object you can just go
object?.doSomthing()
You have made it explicit to the compiler and any body who reads your code, that its possible object is nil and nothing will happen. Some times you have a few lines of code you only want to occur if the value exists, so you can do
if let obj = object {
obj.doSomthing()
doSomethingto(obj)
}
The two statements will only execute if object is something, simarly you may want to stop the rest of the entire block of code if its not something
guard let obj = object {
return
}
obj.doSomthing()
doSomethingto(obj)
This can be simpler to read if everything after is only applicable if object is something, another possiblity is you want to use a default value
let obj = object ?? <default-object>
obj.doSomthing()
doSomethingto(obj)
Now obj will be assigned to something even if its a default value for the type
options are useful in situation where a value may not gain a value until some event has occurred or you can use setting an option to nil as a way to say its no longer relevant or needs to be set again and everything that uses it has no point it doing anything with it until it is set, one way I like to use optionals is to tell me something has to be done or if has already been done for example
func eventFired() {
guard timer == nil else { return }
timer = scheduleTimerToCall(method, in: 60)
}
func method() {
doSomthing()
timer = nil
}
This sudo code can call eventFired many times, but it's only on the first call that a timer is scheduled, once the schedule executes, it runs some method and sets timer back to nil so another timer can be scheduled.
Once you get around your head around variables being in an undefined state you can use that for all sort of thing.
It's very simple. Optional (in Swift) means a variable/constant can be nullable. You can see that Kotlin language implements the same thing but never calls it an 'optional'. For example:
var lol: Laugh? = nil
is equivalent to this in Kotlin:
var lol: Laugh? = null
or this in Java:
#Nullable Laugh lol = null;
In the very first example, if you don't use the ?symbol in front of the object type, then you will have an error. Because the question mark means that the variable/constant can be null, therefore being called optional.
Here is an equivalent optional declaration in Swift:
var middleName: String?
This declaration creates a variable named middleName of type String. The question mark (?) after the String variable type indicates that the middleName variable can contain a value that can either be a String or nil. Anyone looking at this code immediately knows that middleName can be nil. It's self-documenting!
If you don't specify an initial value for an optional constant or variable (as shown above) the value is automatically set to nil for you. If you prefer, you can explicitly set the initial value to nil:
var middleName: String? = nil
for more detail for optional read below link
http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values