Objective-C 中的 bool、Boolean 和 BOOL 之间有啥区别吗?

Posted

技术标签:

【中文标题】Objective-C 中的 bool、Boolean 和 BOOL 之间有啥区别吗?【英文标题】:Is there any difference between bool, Boolean, and BOOL in Objective-C?Objective-C 中的 bool、Boolean 和 BOOL 之间有什么区别吗? 【发布时间】:2011-03-02 07:18:42 【问题描述】:

我知道 BOOL 实际上是有符号字符的 typedef,但是 Boolean 呢?

bool、Boolean 和 BOOL 有什么区别?

【问题讨论】:

Objective-C 没有名为“Boolean”或“bool”的类型,您能澄清一下您的问题吗? 不知道,CF库中出现布尔值... 当然可以。它是 C,所以它也有这些。还有 C++ 的东西。 【参考方案1】:

Boolean 是一个旧的 Carbon 关键字(历史 Mac 类型),定义为 unsigned charBOOL 是定义为 signed char 的 Objective-C 类型。 bool_Bool 标准 C 类型的定义版本。它被定义为int。使用BOOL

编辑(2019 年):Apple 在一些 new documentation 中谈到了 BOOL 的底层实现。基本上,在 macOS 上,BOOL 最终还是一个signed char,但在 ios 和相关平台上,它下面是一个原生 C bool

【讨论】:

Boolean 在 CoreFoundation 中使用(Carbon 主要建立在现在之上),所以虽然你应该在 Objective-C 中使用 BOOL,但在处理任何 CoreFoundation API 时,布尔值仍在使用中. 哦,我明白了,所以我应该使用 BOOL 进行常用,而在 CF 中使用 Boolean。谢谢! 哎呀,你是对的。 CoreFoundation 确实定义了 Boolean 的一个版本,但这与 Carbon 的定义是分开的。请参阅 MacOSTypes.h 与 OSTypes.h。在不使用 C99 的 64 位系统上,CoreFoundation 的 Booleanunsigned char 如果stdbool.h包含在C99中,那么bool是一个扩展为_Bool的宏,它是一个内置的真布尔类型,代表0或1,它不是@ 987654341@. 如今,除了与使用其中一种较旧类型的现有 API 进行互操作外,应该始终使用 bool(包括 stdbool.h,如果不是在 [Objective] C++ 中编码)。使用真正的布尔类型(只能取值 0 和 1,任何非零整数都会自动转换为 true)消除一整类可能的错误。【参考方案2】:

我不想从@JonShier 的有用答案中删除,但我要添加的内容比评论中的内容要多...

bool

在 C99 规范中引入标准 C。 (C99 标准于 1999 年发布,但在此之后几年后才被广泛使用。)在此之前,“普通”C 没有内置的布尔类型,因此构建的库在 C 之上经常定义自己的。 (并且即使在他们采用 C99 编译器之后,也经常继续使用他们自己的类型来实现源代码/二进制文件的兼容性。)

如果您正在编写 ISO C 并且不在具有自己的布尔类型的更高级别库的上下文中工作,请使用此选项。

Boolean

由 Carbon 定义(来自更老的 Mac Toolbox 的早期 OSX 兼容性桥),您可能仍会在某些项目中看到它(由于传递 #include 的标头实际上只是为了与真正旧的兼容而存在源代码)。

不要使用这个。

BOOL

由 ObjC 定义,因为 NeXTSTEP 早在 1988 年就需要自己的布尔类型。(我在办公室书架上能找到的最古老的 objc.h 可以追溯到 1992 年,其中包括 BOOL 的定义。)

ObjC BOOL 通常被定义为typedef signed char,这意味着它可以保存的值不仅仅是YES (1) 和NO (0)。 That can be a problem if you aren't careful。 (为什么还要这样做呢?因为如果一个类型有点宽,那么很难将其装入对齐良好的内存中以获得良好的性能。)

但是,在 iOS 64 位(包括 tvOS)和 watchOS 中,编译器定义了 OBJC_BOOL_IS_BOOL,这使得 ObjC BOOL 只是 C99 bool 的别名。这意味着语言/编译器确保非零值始终存储为 1,因此您不会遇到来自 typedef signed char BOOL 的问题。 (不过,在 macOS 或 32 位 iOS 上仍然需要担心它们。)

TLDR

如果您使用 ObjC 框架(如 Cocoa、UIKit 等)在 ObjC 中工作,您应该使用 BOOL 以与您正在交互的 API 保持一致。 (此外,YESNOtruefalse 响亮得多,当你在谈论绝对真理时,最好强调一下,对吧?)

【讨论】:

【参考方案3】:

如果您的新 API 不需要与旧 API 交互,bool 比 BOOL 更具体、更清晰。

使用 Xcode 9 构建非 Mac 应用程序时,BOOL v = 2; NSLog(@"%d", v); 输出“1”,而不是“2”。

参考Apple documentation

【讨论】:

以上是关于Objective-C 中的 bool、Boolean 和 BOOL 之间有啥区别吗?的主要内容,如果未能解决你的问题,请参考以下文章

从 Objective-C 中的 ColdFusion 布尔返回类型获取 BOOL 的更好方法?

Objective-C 中的 NSThread 错误

Objective-C:BOOL vs bool

Objective-C数据类型之id,SEL,BOOL,nil,NULL和NSNull

在 Swift 中,Objective-C BOOL 被推断为 `()` 而不是 Bool

如何在 Objective-C 中将 BOOL 变量作为参数传递?