Explicitly unwrapping optional nil does not cause crash

前端 未结 2 1676
不思量自难忘°
不思量自难忘° 2021-01-18 17:05

A few folks asked this question before, yet no answer was accepted.

I have a UITableViewCell that contains a UITextField.

If I clic

相关标签:
2条回答
  • 2021-01-18 17:39

    One way to think this as a choise of the API Implementor. If implementor handles the input arguments it will not be any problem to the API User.

    Lets create a drawing text class which just prints at console.

    class TextDrawer {
    
      var mustBeText: String!
    
      func renderText(string: String) {
          print(string)
      }
    
      func renderSafely() {
         renderText(string: self.mustBeText ?? "Nothing found to be rendered")
         // or 
         if let safeString = self.mustBeText {
            renderText(string: safeString)
         }
      }
    
      func renderUnsafely() {
          renderText(string: mustBeText)
      }
    }
    

    We have defined the mustBeText as String! means we are allowed to expect any string as well as nil argument.

    Now, as we create a instance of the class as below:

    let textDrawer = TextDrawer()
    textDrawer.mustBeText = nil // this is allowed since the `mustBeText` is `String!`.
    
    textDrawer.renderSafely() // prints -- Nothing found to be rendered
    
    textDrawer.renderUnsafely() // crashes at runtime.
    

    The renderUnsafaly() will crash since its not handling the nil case.

    0 讨论(0)
  • 2021-01-18 17:40

    As of Swift 3, “Implicitly unwrapped optional” is not a separate type, but an attribute on the declaration of a regular/strong optional. For the details, see SE-0054 Abolish ImplicitlyUnwrappedOptional type.

    A function with an IUO return type can return nil, and assigning the return value to a variable makes that a regular optional:

    func foo() -> Int! {
        return nil
    }
    
    let x = foo() // Type of `x` is `Int?`
    print(x) // nil
    

    Only if evaluation as an optional is not possible then the value will be forced-unwrapped (and cause a runtime exception is the value is nil):

    let y = 1 + foo() // Fatal error: Unexpectedly found nil while unwrapping an Optional value
    

    In your case, your

    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath!
    

    method overrides the UITableViewController method

    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
    

    and can return nil. This does not crash unless the caller unwraps the value.


    Remark: The above is meant as an explanation why your code compiles and works. Generally, I do not see a good reason to use implicitly unwrapped optional return types. The main use-cases of IUOs are stated in SE-0054:

    The ImplicitlyUnwrappedOptional ("IUO") type is a valuable tool for importing Objective-C APIs where the nullability of a parameter or return type is unspecified. It also represents a convenient mechanism for working through definite initialization problems in initializers.

    0 讨论(0)
提交回复
热议问题