NSHipster Obscure Topics in Cocoa and Objective C

BOOL / bool /Boolean / NSCFBoolean

Name Type Header True False
BOOL signed char / bool objc.h YES NO
bool _Bool (int) stdbool.h true flase
Boolean unsigned char MacTypes.h TRUE FLASE
NSNumber __NSCFBoolean Foundation.h @(YES) @(NO)

BOOL

Objective-C defines BOOL to encode truth value. It is a typedef of a signed char, with the macros YES and NO to represent true and false, respectively.一般是在Objective-C定义的BOOL,它是一个有符号的char类型,它的值是YES或NO来代替true或false。

Boolean

Boolean values are used in conditionals, such as if or while statements, to conditionally perform logic or repeat execution. When evaluating a conditional statement,the value 0 is considered "false", while any other value is considered "true". Because NULL and nil have a value of 0, they are considered "false" as well.

In Objective-C, use the BOOL type for parameters, properties, and instance variables dealing with truth values. When assigning literal values, use the YES and NO macros.

The Wrong Answer to the Wrong Question

  1. wrong(容易出错的情况)

    if ([a isEqual:b] == YES) { ... }
    
    static BOOL different (int a, int b)
    {
      return a - b;
    }
    
    different(11, 10) == YES// YES
    different(10, 11) == YES// NO (!)
    different(512, 257) == YES// NO (!)
    

    However, because BOOL is typedef 'd as a signed char on 32- bit architectures, this will not behave as expected:

    On a 64-bit iOS, BOOL is defined as a bool, rather than signed char, which precludes the runtime from these type conversion errors.

  2. right

    if ([a isEqual:b]) { ... }
    
    static BOOL different (int a, int b)
    {
      return a != b;
    }
    
    different(11, 10) == YES// YES
    different(10, 11) == YES// YES (!)
    different(512, 256) == YES // YES (!)
    

    Deriving truth value directly from an arithmetic operation is never a good idea. Use the == operator, or cast values into booleans with the ! (or !!) operator.

The Truth About NSNumber and BOOL

NSLog(@"%@", [@(YES) class]);

__NSCFBoolean

All this time, we've been led to believe that NSNumber boxes primitives into an object representation. Any other integer or float derived NSNumber object shows its class to be __NSCFNumber. What gives?

NSCFBoolean is a private class in the NSNumber class cluster. It is a bridge to the CFBooleanRef type, which is used to wrap boolean values for Core Foundation collections and property lists. CFBoolean defines the constants kCFBooleanTrue and kCFBooleanFalse. Because CFNumberRef and CFBooleanRef are different types in Core Foundation, it makes sense that they are represented by different bridging classes in NSNumber.