Why is Swift implicitly expanding the optional "nil" parameter?

self.presentTextInputControllerWithSuggestions(nil, allowedInputMode: WKTextInputMode.Plain) { (results:[AnyObject]!) -> Void in
    // results can be nil
    if let speech = results.first as? String {
        debugPrint(speech)
    }
}

      

Excuse my ignorance, I'm afraid I missed some basic understanding of the alternatives. My impression is that the !

optional unwrapped optional indicator is a guarantee that a variable of this type is not null. However, this very simple API Apple will rarely return to me nil

.

Is this an unexpected bug or part of the spec for options? Because if this is part of the specification, I don't understand why there are options in the first place and not variables that may be present, or nil

.

+3


source to share


3 answers


I am under the impression that the !

optional unwrapped optional indicator is a guarantee that a variable of this type is not null.

This is a wrong impression. I'm afraid. Implicitly expanded options can be very nil

. Only what is not declared with any optional qualifier is neither ?

, nor is !

it guaranteed nil

.

So:



var definitelyCouldBeNilForcedToCheck: String?
var mightBeNilButProbablyNotBECAREFUL: String!
var definitelyNotEverNil: String

      

There are two use cases for implicitly expanded options:

  • When you are absolutely sure that your value will not be there nil

    , except for a short time in very controlled circumstances. For example, suppose you have a function that does some processing in its failover initializer. Like this:

    class FileHandler {
        let fileHandle: SomeFileHandleType!
    
        init?(fileName: String) {
            fileHandle = open(fileName)
            if fileHandle == nil { return nil }
        }
    
        deinit {
            if fileHandle != nil {
                fileHandle.close()
            }
        }
    
        func variousMethods() {
            // can just use fileHandle without bothering about
            // unwrapping it, because it cannot possibly be nil
            // based on how you’ve written your code
        }
    }
    
          

  • If you have a massive Objective-C corpus (say Cocoa or UIKit) and you don't know when any pointer is returned, whether it might nil

    or not. And most of the time you think that this is probably not the case, and it would be very frustrating for your API users to constantly unwrap stuff, but then again, you don't know for sure that it cannot be nil, and you want they read the documentation instead, but they'll probably forget, but what can you do? Eventually, you will test all the functions and then make them non-nullable options or values.

+7


source


Whenever you see a method signature with an operator !

like this, you should check it for nil

.

In most cases, the argument will be implicitly unwrapped unnecessarily because it is from an Objective-C library that has not yet been updated to account for the Objective-C zero probability annotations (which Objective-C uses for Swift source code files, should the argument be optional).



Objective-C doesn't support the idea of ​​options.

If it's from the Apple library, it's only a matter of time before they release an Xcode update that fixes this and change the argument to both optional and optional. Apple has no long term plans to keep any implicitly expandable options in its parameters.

+1


source


No, this symbol is !

not a guarantee that the variable is not null.

Swift options are tricky.

let's say you have the following variable of type String

var name: String?

      

This is not a string. This is an optional string that is different.

however the following:

var name: String!

      

is an implicitly expanded optional parameter that means that the call name will always contain a non-optional string, which can be null.

Typically, an implicitly expanded optional is used if you want your code to work when the optional parameter is zero.

0


source







All Articles