题 Objective-C:BOOL vs bool


我看到了“新型” BOOL (YESNO)。

我读到这种类型几乎就像一个字母。

为了测试,我做了:

NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));

很高兴看到两个日志显示“1”(有时在C ++中bool是一个int,其sizeof是4)

所以我只是想知道bool类型是否存在某些问题?

我可以在不失速的情况下使用bool(看似有效)吗?


183
2018-02-12 13:46


起源




答案:


从定义中 objc.h

#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
typedef bool BOOL;
#else
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

#define YES ((BOOL)1)
#define NO  ((BOOL)0)

所以,是的,你可以假设BOOL是一个char。你可以使用(C99) bool 类型,但所有Apple的Objective-C框架和大多数Objective-C / Cocoa代码都使用BOOL,所以如果仅使用BOOL改变typedef,你将会自己头疼。


190
2018-02-13 00:43



“Apple的所有框架” - 不是真的。看看CGGeometry.h,具体来说:CG_INLINE bool __CGPointEqualToPoint(CGPoint point1,CGPoint point2){return point1.x == point2.x && point1.y == point2.y; } - Elliot
@Elliot你是对的。许多C框架(CoreFoundation,CoreGraphics等)都使用C99 bool。所有Objective-C框架都使用 BOOL。 - Barry Wark
所有的苹果Objective-c框架 - Aran Mulholland
@Cœur您已经编辑了BOOL代码示例的定义,但下面的文本保持不变。这有点令人困惑,不正确。看到我的回答。 - curious
要了解不同的行为,请看下面。 NSInteger progressTime = 2;//any value NSInteger totalTime = 1;//any value BOOL success = (progressTime>=totalTime)//总是给出 NO  但是一旦我收到了 (progressTime>=totalTime) 价值进入 bool 类型 success 它返回正确的结果。我不明白这种行为。我在用 Xcode 7.x 和 iOS 版本是 8.x。 @BarryWark - Kamarshad


如上所述,BOOL是一个签名字符。 bool - 来自C99标准(int)。

BOOL - 是/否。 bool - 真/假。

见例子:

bool b1 = 2;
if (b1) printf("REAL b1 \n");
if (b1 != true) printf("NOT REAL b1 \n");

BOOL b2 = 2;
if (b2) printf("REAL b2 \n");
if (b2 != YES) printf("NOT REAL b2 \n");

结果是

REAL b1
  REAL b2
  不是真的b2

注意bool!= BOOL。以下结果仅供参考 再一次 - 真正的b2 

b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");

如果你想将bool转换为BOOL,你应该使用下一个代码

BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;

所以,在我们的案例中:

BOOL b22 = b1 ? 2 : NO;
if (b22)    printf("ONCE AGAIN MORE - REAL b22 \n");
if (b22 != YES) printf("ONCE AGAIN MORE- NOT REAL b22 \n");

那么......我们现在得到了什么? :-)


32
2018-06-22 09:01



你可以,而不是使用三元运算符 !!b1。在他们之间进行转换 - Richard J. Ross III
我的iPhone SE模拟器上没有打印“NOT REAL b2”。 - gabbler


在撰写本文时,这是objc.h的最新版本:

/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

这意味着在64位iOS设备和WatchOS上 BOOL 是完全一样的 bool 而在所有其他设备(OS X,32位iOS)上 signed char 甚至不能被编译器标志覆盖 -funsigned-char

这也意味着此示例代码将在不同平台上以不同方式运行(我自己测试):

int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
    printf("i'm 64-bit iOS");
} else {
    printf("i'm 32-bit iOS");
}

BTW永远不会分配像 array.count 至 BOOL 变量因为约0.4%的可能值将为负数。


11
2017-10-30 15:24





你应该使用的Objective-C类型是 BOOL。没有什么比本机布尔数据类型更好,因此要确保代码编译在所有编译器上使用 BOOL。 (它在Apple-Frameworks中定义。


8
2018-02-12 14:08



这不是严格准确的。 BOOL 由Objective-C语言定义(它在其中一个 objc/*.h 标题),而不是框架。此外,当使用C99(我认为是默认值)进行编译时,则存在本机布尔类型, _Bool (要么 bool 如果 stdbool.h 已经包括了)。 - dreamlax


根据objc.h,Yup,BOOL是签名字符的typedef.

不过我不知道bool。这是C ++的事情,对吧?如果它被定义为一个有符号的字符,其中1是YES / true而0是NO / false,那么我想你使用哪一个并不重要。

但是,由于BOOL是Objective-C的一部分,因此为了清晰起见使用BOOL可能更有意义(如果他们看到使用bool,其他Objective-C开发人员可能会感到困惑)。


5
2018-02-12 14:02



_Bool在C99中定义,在标准头文件stdbool.h中,定义宏bool(扩展为_Bool),并在此定义true / false。 - Brian Mitchell


bool和BOOL之间的另一个区别是,当您进行键值观察时,或者使用类似 - [NSObject valueForKey:]的方法时,它们不会完全转换为相同类型的对象。

正如大家在这里所说,BOOL是char。因此,它被转换为持有char的NSNumber。此对象与从常规字符“A”或“\ 0”创建的NSNumber无法区分。您完全丢失了原本拥有BOOL的信息。

但是,bool被转换为CFBoolean,其行为与NSNumber相同,但保留了对象的布尔原点。

我不认为这是BOOL与bool辩论中的争论,但有一天这可能会让你感到厌烦。

一般来说,你应该使用BOOL,因为这是Cocoa / iOS API中所使用的类型(在C99及其原生bool类型之前设计)。


4
2018-05-08 08:12





已接受的答案已被编辑,其解释变得有点不正确。代码示例已刷新,但下面的文本保持不变。你现在不能认为BOOL是一个char,因为它依赖于架构和平台。 因此,如果您在32位平台(例如iPhone 5)上运行代码并打印@encode(BOOL),您将看到“c”。它对应于a char类型。 但如果你在iPhone 5s(64位)运行代码,你会看到“B”。它对应于a 布尔型


2
2018-02-13 13:20