Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2: !, ? -" Value of optional type "..." not unwrapped"

Tags:

swift

swift2

Value of optional type "..." not unwrapped; did you mean to use '!' or '?'?

Can someone explain me what this error message exactly means? When should I use '?' and when '!'?

like image 935
digitalangel Avatar asked Nov 07 '15 20:11

digitalangel


People also ask

Why use implicitly unwrapped Optional?

Outlets are a common example when discussing implicitly unwrapped optionals. Why does Apple use implicitly unwrapped optionals to declare outlets? The reason is simple. Every stored property of a class needs to have a valid value before the initialization of the instance is complete.

What is implicitly unwrapped Optional in Swift?

Checking an optionals value is called “unwrapping”, because we're looking inside the optional box to see what it contains. Implicitly unwrapping that optional means that it's still optional and might be nil, but Swift eliminates the need for unwrapping.

What does it mean to unwrap in Swift?

Unwrapping in Swift is essentially verifying if the Optional value is nil or not, and then it performs a task only if it's not nil. You can perform unwrapping in the following ways: Using an if else block. Using Forced unwrapping. Using Optional binding.

What are optionals in Swift?

An Optional is a type on its own, actually one of Swift 4's new super-powered enums. It has two possible values, None and Some(T), where T is an associated value of the correct data type available in Swift 4.


2 Answers

obj?.fn() calls fn member function if the object isn't null, otherwise doesn't do anything.

obj!.fn() on the other hand asserts that obj isn't null, and calls fn. If the object is null, you get an exception.

So it's a difference in assertiveness: you either ask or simply claim the nullable property of a nullable object.

like image 102
Blindy Avatar answered Oct 25 '22 12:10

Blindy


What is a String?. Is it a String that is optional or is it an optional that 'has an associated value of String'.

Only the 2nd definition is correct. To access any member/property on String or to run a function on a string you MUST do it on the 'associated value of the optional' which requires you to unwrap the optional.

I know of 2 ways that this error could be created:

1st

if you have

@IBOutlet weak var display : UILabel? // FYI IBOutlets must be optional...
let something = display.text // Line C
let something = display!.text // Line D

You will get the following error on line C:

Value of optional type 'UILabel?' not unwrapped; did you mean to use '!' or '?'?

This is because you are messaging text onto an optional, but the optional itself doesn't have any understanding of text method, however its 'unwrapped associated value'—UILabel! can understand. Therefore you must write it as line D

Having that said the correct approach is to just unwrap UILabel from the beginning and then easily accessing its text as such:

@IBOutlet weak var display : UILabel!
let something = display.text 

2nd

cell.textLabel?.text = bug.name // Line A: you are messaging text on *optional* textLabel
cell.textLabel.text = bug.name // Line B: you are messaging text on textLabel

on Line B you are accessing textLabel which is an optional that has an associated type of UILabel. It will create the following error:

Value of optional type 'UILabel?' not unwrapped; did you mean to use '!' or '?'?

You can go to UITableViewCell.swift and see that it is declared as:

public var textLabel: UILabel? { get } // default is nil.  label will be created if necessary.

UILabel? is a property in an optional form.

like image 23
mfaani Avatar answered Oct 25 '22 12:10

mfaani