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 char
。 BOOL
是定义为 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 的 Boolean
是 unsigned 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 保持一致。 (此外,YES
和 NO
比 true
和 false
响亮得多,当你在谈论绝对真理时,最好强调一下,对吧?)
【讨论】:
【参考方案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数据类型之id,SEL,BOOL,nil,NULL和NSNull