Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should all object variables be optional in Swift?

Tags:

swift

Swift Programming Language book doesn't discuss this but should all object variables be optional in Swift? Because technically speaking, an object creation can fail and return nil (as in the case of Objective-C). So should all object variables in Swift for Swift classes (or at least for all Foundation classes) be declared as optional?

let obj:NSData? = NSData()
like image 854
Boon Avatar asked Jun 15 '14 16:06

Boon


1 Answers

This might be opinion based but I think that usually you want variables to be non-optional. There are not many objects initializers that can actually return a nil.

In Obj-C you don't check whether all initialisers return nil.

NSArray *array = [[NSArray alloc] init];

if (array != nil) {  //would you test this?
}

In the same way, don't let all object variables be optional in Swift. Only the ones when you actually want to check for nil values.

By the way, in pure Swift the Object initializers can't return a nil because they don't actually have a return value. In Swift, the object initialization can't fail, so we are speaking only about Obj-C interoperability here.

One example to answer the comments:

NSData *data = [[NSData alloc] initWithContentsOfFile:@"some_file"];

in Swift:

var data = NSData(contentsOfFile: "some_file")

If the file doesn't exist, in both languages we get a nil. In Swift, we have an implicitly unwrapped optional, so the assignment itself won't fail and we can still test for nil if we want to.

If we expected data could be nil, the behavior would be the same in both languages, we would solve the problem somehow. If we haven't expected it, it's a bug because everything else is undefined behavior.

In Swift, the application will crash early - the first time you try to use data. In Obj-C, the result will be absolutely random - note that we never expected data to be nil, so our next statement could be:

[array addObject:data];

crashing the application.

However, because of the nature of Obj-C, thousands of statements could happen before the bug actually reveals itself and it can reveal itself very strangely - for example: data parsing could fail, UI layout will fail because items will be missing when we expected them and so on. We could also get a late crash. Nevertheless, the application behavior will be undefined since the nil return because we didn't account for that possibility:

...things may not be executed, but it certainly won't crash the program or leave things in an unstable state...

Both statements from the comment are false.

The late manifestation of errors is one of the biggest problems when debugging Obj-C applications, making them unsafe. Sometimes they don't crash but that doesn't mean they are working correctly. Swift considers and early crash a much better alternative than a hidden nil object propagating itself through the application and crashing the app hours later.

like image 87
Sulthan Avatar answered Sep 30 '22 19:09

Sulthan