Swift Usage Implicitly Unwrapped Optional before nullability

In Apple's blog post about the error, you can say the following:

"... in Swift there is a strong distinction between optional and optional references, eg NSView vs. NSView ?, and Objective-C represents both of these two types as NSView *. Because the Swift compiler cannot tell if a particular NSView * is optional or no, the type is injected into Swift as an implicitly expanded optional, NSView! "

Does this mean earlier, when declaring Objective-C methods as returning implicitly unwrapped optional in Swift, it might actually crash (since some of the methods declared with implicitly unwrapped optional might return nil)? Or is Apple sure that only Objective-C methods that absolutely do not return nil get are declared as implicitly expanded optional?

+3


source to share


2 answers


Apple's frames are nothing special. In the beginning, everything (every object) that you used from Objective-C to Swift was implicitly expanded optionally. This is because every pointer in Objective-C can return nil

.

In fact, even in the era of Objective-C zero-probability annotations, it is not entirely impossible that a method annotated as nonnull

could return nil

. Objective-C does not enforce nullability rules, it just provides a means to annotate your code so it can be used more safely from Swift. In the case of Apple's wireframes, I'd put myself in a pretty safe bet that you won't have this problem. Or, if you do, the next version of Xcode will fix it.

But then again, there is nothing special about the implicitly expanded options from Objective-C libraries and frameworks. The only thing that is not necessarily expanded implicitly is that the author of the framework has not yet made an attempt to annotate their library (you cannot leave implicitly expanded options in an annotated library). And yes, these implicitly expanded options can be nil

, and they can crash your application.

In Apple's case, if for some reason you are using, say, Xcode 7 and Xcode 6 for different projects, if you take that Xcode 7 update annotations are declared optional, then it is assumed that the implicitly deployed optional version in Xcode 6 is never It not nil

can work. But if you take something that is optional in Xcode 7, assuming the implicitly deployed version from Xcode 6 will never be nil

, it probably has a decent chance of crashing your application.

Ultimately, in Swift, our use of implicitly expanded options should be a bit and far away. The main use of implicitly expanded options is to be reserved for class properties that cannot be set before the return of the class initialization (for example, @IBOutlets

in a view controller). If not, they tend to be the source of numerous "Suddenly Found Questions" here in the Stack Overflow section.


To the question "Why return an implicitly expanded optional and not optional?", A few dots ...

First, it is a matter of language design. I'm not on the Objective-C or Swift development team, and hardly any of these teams will stop and answer this question ...

Second, how languages ​​are designed to communicate. Any Objective-C file that does not have zero probability annotations added will be treated as if everything were implicitly deployed in Swift.



Third, the reason for the implicit options is that it reduces the number of words if let

, etc., which would not necessarily require, without guaranteeing that this variable is in fact non-nil

. Most of the reasons for this are likely because you think most of these methods never return nil

.

Fourth, if you know who has a chance to be nil

and which doesn't, you can go ahead and write your Swift code in such a way that it treats like assumptions about how Objective-C code will be annotated.

For example, with an implicitly expanded optional, of course you can treat it as optional and remove some of the minor verbosity associated with unboxing.

Also, with an implicitly expanded additional, if you think it might be nil

, all additional expansion files can work with it.

Example:

override func someFunc(implicitVal: String!) -> String {
    return implicitVal ?? "It was nil!"
}

override func someOtherFunc(implicitVal: String!) -> String {
    return implicitVal
}

      

If we took them as optional, the second example would not work.

If we assumed they were not optional, the first example will not work.

Implicitly expandable options allow the Swift developer's freedom to treat them as either, as long as they make a correct assumption about the likelihood that the value is nil

.

+6


source


Does this mean earlier when declaring Objective-C methods as returning implicitly, unwrapping optionally in Swift, it might actually crash (since some of the methods declared implicitly unwrap might not necessarily return nil)?

Not. Optional - Expands the optional variant - this means that it nil

is a perfectly acceptable value for it. Unless the implicitly expanded optional parameter nil

fails, only if you try to access the element on it directly without optional binding or optional chaining, it will fail.



Or is Apple sure that only Objective-C methods that absolutely do not return nil get are declared implicitly Expanded optional?

If it was known that it was not returning nil

, then Apple will declare it optional after auditing, rather than implicitly expanding optional. Only if it is not known whether it can return nil

or not, whether it returns implicitly, it does not necessarily unfold.

+1


source







All Articles