ppalancica
ppalancica

Reputation: 4277

Which is the correct way to check for null in Swift?

I am supposed to refactor this line of Objective-C code:

if (_currentImageFrame && ![_currentImageFrame.isSaveToLibrary boolValue]) {}

I think of 2 ways to achieve this, but I am not sure which one is better:

1)

if (self.currentImageFrame != nil) &&
   (self.currentImageFrame?.isSaveToLibrary == false)
{
}

2)

if let frame = self.currentImageFrame {

    if self.currentImageFrame?.isSaveToLibrary == true {
    }
}

Please let me know which is more recommended/correct way to achieve it.

Thanks in advance!

Upvotes: 0

Views: 1003

Answers (2)

Ricardo Sanchez-Saez
Ricardo Sanchez-Saez

Reputation: 9566

Since self.currentImageFrame is an optional, the more compact way of doing what you ask is taking advantage of the way optional chaining works:

if self.currentImageFrame?.isSaveToLibrary == false
{
    // Code
}

If self.currentImageFrame is not nil, self.currentImageFrame?.isSaveToLibrary will return the value of isSaveToLibrary.

If self.currentImageFrame is nil, self.currentImageFrame?.isSaveToLibrary will return nil immediately, without attempting to execute anything that's after the ? (no matter how deep the chain goes).

nil does not equal false (unlike Objective-C, in Swift nil only equals nil and nothing else), hence nil == false evaluates to false, so the code behaves as you would expect.


Note that your 1) option would work but it's completely redundant, as the first check is not needed at all.

I think that your 2) option has a typo, and you intended to write false where you typed true. With the typo fixed it would work as well (since you are actually using optional chaining once again inside the outer condition), but it's using optional binding in a wrong way, since you don't use the the bound constant frame inside the outer conditional body. A more correct (although redundant as well) way of using optional binding would be.

if let frame = self.currentImageFrame
{
    if frame.isSaveToLibrary == false
    {
        // Code
    }
}

In this case you don't use optional chaining at all. (Although I suspect that the optimized compiled code would be the same in both cases).


Finally, I suggest you rename isSaveToLibrary as it's grammatically incorrect and its meaning is unclear. I would name it wasSavedToLibrary or shouldSaveToLibrary, depending on the intended use.

Upvotes: 1

diegomen
diegomen

Reputation: 1864

I would use the following:

if self.currentImageFrame?.isSaveToLibrary == true {
    // Stuff
}

Your var currentImageFrame is ? so you don't have to check if it's nil, in case of nil, it is not going to check the if condition, and if it's not nil it is going to check the if and if the condition is satisfied it will enter. Furthermore you don't need to use parenthesis in Swift :)

Upvotes: 2

Related Questions