Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forced unwrapping vs not

Tags:

swift

Facebook recently updated Parse to support Swift. One of the code examples it gives is this:

var gameScore = PFObject(className: "GameScore")
gameScore.setObject(1337, forKey: "score")
gameScore.setObject("Sean Plott", forKey: "playerName")
gameScore.saveInBackgroundWithBlock { 
(success: Bool!, error: NSError!) -> Void in
    if success {
        NSLog("Object created with id: \(gameScore.objectId)")
    } else {
        NSLog("%@", error)
    }
}

I'm curious about this part: "(success: Bool!, error: NSError!)", in particular the point of the exclamation marks. My understanding of optionals was something like this:

NSError: this is an NSError, and cannot be nil. NSError?: this might include an NSError or it might be nil, but it needs to be unwrapped first. NSError!: this is a force-unwrapped NSError?, and thus cannot be nil.

Facebook's example says that success is a Bool! and error is an NSError! - ie, they are both definitely provided. How come they aren't just written as Bool and NSError, providing that Facebook has unwrapped them before sending them on? Also, how can both success and error both be set? Traditional use of NSError would say that it's set to nil when there's no problem.

like image 928
FizzBuzz Avatar asked Jun 13 '14 14:06

FizzBuzz


People also ask

Should Iboutlets be optional or implicitly unwrapped?

The outlet is declared as an implicitly unwrapped optional, not an optional. Remember that the @IBOutlet Interface Builder attribute indicates the property is an outlet.

How does Swift handle force unwrap?

Even though Swift isn't sure the conversion will work, you can see the code is safe so you can force unwrap the result by writing ! after Int(str) , like this: let num = Int(str)! Swift will immediately unwrap the optional and make num a regular Int rather than an Int? .

What happens when an optional is unwrapped and it does not contain a value?

Unwrap an optional type with the nil coalescing operator If a nil value is found when an optional value is unwrapped, an additional default value is supplied which will be used instead. You can also write default values in terms of objects.

Why use implicitly unwrapped optional?

Implicitly unwrapped optionals are useful when an optional's value is confirmed to exist immediately after the optional is first defined and can definitely be assumed to exist at every point thereafter.


1 Answers

It's probabily due to interoperability with Objective-C APIs. Since any object can be nil in Objective-C, those two values have to be optional in Swift.

Anyway - since apparently they guarantee that those objects are never going to be nil - they can afford to implicitly unwrap them, allowing whoever uses this API to save a few unwraps, which is nice.

Concerning your statement

Traditional use of NSError would say that it's set to nil when there's no problem.

This is just wrong, even in Objective-C.

The BOOL/NSError pattern in Cocoa dictates that you have to check the success value to know whether an error occured, and - if that's the case - then the NSError will contain information about it.

Checking for NSError to be nil is a common misuse of this pattern, and it can lead to logic errors in your code, as some Apple APIs return a non-nil error even in case of success.

like image 108
Gabriele Petronella Avatar answered Oct 26 '22 02:10

Gabriele Petronella