简体   繁体   中英

Swift Optional Unwrapping Syntax

I am relatively new to Swift. Whilst doing some reading, I found the following sample code for programmatically creating a UINavigationController in the app delegate:

let mainVC = ViewController.init()
let nc = UINavigationController.init(rootViewController: mainVC)
self.window = UIWindow.init(frame: UIScreen.main.bounds)
self.window!.rootViewController = nc
self.window?.makeKeyAndVisible()

My question relates to the last line " self.window?.makeKeyAndVisible() ". I would have expected it to use ! to unwrap self.window similar to the line above, but instead ? was used. I tried this code with both the ! and the ? and in both cases the app compiled and ran successfully.

What I would like to know is which punctuation (! or ?) is the best to use and why please?

  1. If you use ? to unwrap an object if the object is null the app won't crash.(? notation will skip unwrapping, given the object is nil)
  2. If you use ! to unwrap an object and if the object is null the app will crash. (you use ! when you expect the object, that it will never be nil).

Consider the following code snippet:

var tentativeVar: Array<Any>?
tentativeVar = Array()
tentativeVar?.append("FirstElement")

Now if you print the tentativeVar with optional unwrapping(using ?), you will get the following results.

(lldb) po tentativeVar?[0]
 Optional<Any>
  - some : "FirstElement"

For the same if you force unwrap the variable you can directly get the object omitting the unnecessary optional data.

(lldb) po tentativeVar![0]
"FirstElement"

For the same object if you don't initialise the object and try to access an element in it the following things will happen.

print("\(tentativeVar?[0])") //prints nil
print("\(tentativeVar![0])") //Crashes the app, trying to unwrap nil object.

What you are seeing is optional chaining . It differs slightly from optional unwrapping, since you aren't always assigning the result to a variable.

self.window!.rootViewController = nc will crash if window is nil. self.window?.rootViewController = nc will do nothing at all if window is nil.

There's no benefit to force unwrapping the chain if you're not assigning it to a variable, so it's generally better to use ? unless you want your app to crash on a nil (if you do want that, I would suggest instead implementing your own error handling that reports some details on what went wrong).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM