7

So in Objective-C when using Booleans it's possible, and encouraged, to write code using a variable's non-zero value as it's boolean value, which means you can write code like this:

if (someBool) {
    // Stuff
}

Also, there are reasons why code like the following is discouraged:

if (someBool == YES) {
    // Might run into problems here
}

The reasons why checking a boolean against another boolean are better explained here, but briefly the issue is just that when you're comparing equality to YES or NO directly, you're actually comparing against 1 and 0, respectively. Since Objective-C allows for using non-zero values as a truth value, you could end up comparing something that should be considered true against YES and have the expression resolve to NO, e.g.

int trueNumber = 2;
if (trueNumber == YES) {
    // Doesn't run because trueNumber != 1
}

Is this still an issue in Swift? Code style issues aside, if I see something like the following

var someBool = true
if someBool == true {
    // stuff
}

is that going to be an issue, or does it not really matter? Are these C-style comparisons still happening under the hood, or is there something built into the Swift BooleanType that prevents these issues?

3 Answers 3

3

The if <something> {} structure in Swift requires the <something> to conform to the BooleanType protocol which is defined like this:

public protocol BooleanType {
    /// The value of `self`, expressed as a `Bool`.
    public var boolValue: Bool { get }
}

If the type doesn't conform to this protocol, a compile-time error is thrown. If you search for this protocol in the standard library you find that the only type that conforms to this protocol is Bool itself. Bool is a type that can either be true or false. Don't think of it as the number 1 or 0, but rather as On/Off Right/Wrong.

Now this protocol can be conformed to by any nominal type you want, e.g.:

extension Int : BooleanType {
    public var boolValue : Bool {
        return self > 0
    }
}

Now if you do this (you shouldn't honestly), you're defining it by yourself what "True" and "False" means. Now you'd be able to use it like this (again, don't do this):

if 0 {
    ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Okay, so the reason why the code that was a problem in Objective-C isn't an issue is simply because of the strict type-checking in Swift? It seems like in order to be used in boolean checks in Swift, a type basically has to return a strictly-typed Bool (as you've shown above), which avoids the issue that C and Objective-C had with the typedef signed char. Is it just as simple as that?
2

Swift has Bool type. This is different from objective-c's BOOL which is not actual type. It is actually typedef unsigned char. When swift expects Bool you have to give it Bool otherwise it is compile error. The following code will not compile because check is not Bool

let check = 2
if check {
}

But this will work because == returns Bool

let check = 2
if check == 2 {
}

3 Comments

Actually Bool is its own type in Swift and not a type alias to "unsigned char" (which would be CUnsignedChar in Swift).
Sorry I mean Objective-C not swift
Well, it's more complicated in Objective-C, compare stackoverflow.com/questions/31267325/bool-with-64-bit-on-ios.
0

To understand the ObjC style, you need to go back to C. In C, this statement:

if (something) {
    // Do something
}

will evaluate to false if something is null or 0. Everything else evaluate to true. The problem is C doesn't have a boolean type. Objective-C added YES and NO which is basically 1 and 0. So:

if (aBoolValue == YES) { } // Work as expected
if (anIntValue == YES) { } // False unless anIntValue == 1

The "discouraged" recommendation was to align with the behaviour in C. Swift has no such backward compatibility requirements. You can't write these:

if anIntValue {  } // Syntax error
if anObject { }    // Syntax error

Instead, the expression must evaluate to a boolean value:

if anIntValue != 0 { } // Ok
if anObject != nil { } // Ok

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.