Answers:
从中的定义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是一个字符。您可以使用(C99)bool
类型,但是Apple的所有Objective-C框架和大多数Objective-C / Cocoa代码都使用BOOL,因此,如果仅使用BOOL改变typedef,就可以避免头痛。
bool
。所有的Objective-C框架都使用BOOL
。
NSInteger progressTime = 2;//any value NSInteger totalTime = 1;//any value BOOL success = (progressTime>=totalTime)
//它总是给定的,NO
但是一旦我收到该 类型的(progressTime>=totalTime)
值,它就会返回正确的结果。我不了解这种行为。我正在使用,版本为。@BarryWarkbool
success
Xcode 7.x
iOS
8.x
如上所述,BOOL是带符号的字符。bool-根据C99标准(int)的类型。
布尔-是/否。布尔-正确/错误。
查看示例:
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");
结果是
实数b1实数
b2
不实数b2
请注意,布尔!= BOOL。以下结果仅一次-REAL 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");
所以..我们现在得到什么?:-)
!!b1
。在他们之间转换
在撰写本文时,这是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可能值%将是负面的。
是的,BOOL是根据objc.h的带符号字符的typedef。
我不知道布尔。那是C ++的事情,对不对?如果将其定义为带符号的char,其中1是YES / true,0是NO / false,那么我认为使用哪一个都没有关系。
但是,由于BOOL是Objective-C的一部分,因此使用BOOL进行清晰度可能更有意义(如果其他Objective-C开发人员看到使用的是bool,可能会感到困惑)。
bool和BOOL之间的另一个区别是,在执行键值观察或使用-[NSObject valueForKey:]之类的方法时,它们不会完全转换为相同类型的对象。
就像大家在这里所说的,BOOL是char。这样,它将转换为包含字符的NSNumber。该对象与由常规字符(如“ A”或“ \ 0”)创建的NSNumber不可区分。您已经完全失去了最初拥有BOOL的信息。
但是,布尔值将转换为CFBoolean,其行为与NSNumber相同,但保留了对象的布尔源。
我不认为这是BOOL与bool辩论中的论点,但这可能有一天会困扰您。
一般来说,应该使用BOOL,因为这是Cocoa / iOS API中到处使用的类型(在C99及其原生bool类型之前设计)。
我在这里违反惯例。我不喜欢将typedef设置为基本类型。我认为这是消除价值的无用间接。
size_t
),和两个bool
(C99)和BOOL
(ObjC)属于这一类。而且,如果您的代码由于typedef的更改而失败,则应该归咎于您的代码,因为您显然不是将typedef视为不透明的东西,而是依赖于在一个平台上的实现。(它不会让您感到羞耻,但是,这并不是应该责怪的typedef。)
BOOL varname
而不是布尔char varname
值时,该变量的两个有效值为true
/ YES
或false
/ 更为明显NO
。
如上所述,取决于您的体系结构,BOOL
可以是unsigned char
type,而bool
type是int
。一个简单的实验将显示BOOL和bool行为不同的不同之处:
bool ansicBool = 64;
if(ansicBool != true) printf("This will not print\n");
printf("Any given vlaue other than 0 to ansicBool is evaluated to %i\n", ansicBool);
BOOL objcBOOL = 64;
if(objcBOOL != YES) printf("This might print depnding on your architecture\n");
printf("BOOL will keep whatever value you assign it: %i\n", objcBOOL);
if(!objcBOOL) printf("This will not print\n");
printf("! operator will zero objcBOOL %i\n", !objcBOOL);
if(!!objcBOOL) printf("!! will evaluate objcBOOL value to %i\n", !!objcBOOL);
令您惊讶的if(objcBOOL != YES)
是,编译器将其计算为1,因为YES
实际上它是字符代码1,并且在编译器看来,字符代码64当然不等于字符代码1,因此if语句的计算结果为YES/true/1
,而下一行将跑。但是,由于非零bool
类型始终求值为1的整数,因此上述问题不会影响您的代码。如果您想使用Objective-C BOOL
类型与ANSI C bool
类型,以下是一些很好的技巧:
YES
或NO
值,而别无其他。BOOL
通过使用double not !!
运算符转换类型,以避免出现意外结果。YES
使用if(!myBool) instead of if(myBool != YES)
情况时,使用not !
运算符会更清洁,并给出预期的结果。另外,请注意转换的不同,尤其是在使用位掩码时,由于转换为带符号的char而导致的差异:
bool a = 0x0100;
a == true; // expression true
BOOL b = 0x0100;
b == false; // expression true on !((TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH), e.g. MacOS
b == true; // expression true on (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
如果BOOL是带符号的char而不是bool,则将0x0100强制转换为BOOL只会丢弃设置的位,结果值为0。