像这样遍历Objective-C BOOL是否安全:
for (BOOL flagA = NO; flagA <= YES; flagA++)
for (BOOL flagB = NO; flagB <= flagA; flagB++)
// ...
我希望使用此功能循环浏览XCTestCase
中所有相关的标记排列。
但至少在某些平台上似乎YES++
仍然是YES
(因此导致无限循环,例如在iPhone 6 Plus模拟器上),而我本来期望BOOL
只会被视为int
(因此YES++
会成为2
。
我是否必须循环int
s(我的最佳猜测),或者可以以某种方便的方式挽救BOOL
的使用?
答案 0 :(得分:4)
你们都错过了这一点。 Drux问为什么他不能增加BOOL,而它应该是一个char(8位值),这是完全可递增的。
答案非常简单。 BOOL有时是char,有时是bool
,具体取决于目标。来自objc.h
档案:
#if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__
typedef bool BOOL;
#else
typedef signed char BOOL;
如果您对bool
进行迭代,则最多可获得1
的值。
修改强>
是否可以添加一个引用指定++ for bool语义的位置? - Drux
即使bool
必须至少为8位,它也不能具有除0
或1
之外的任何其他值。为什么?因为bool a = 3
(bool等于运算符)将3
转换为bool
值,true
为1
。
因此bool a = true; a++
与bool a = 2;
相同,因此a
的值为1
答案 1 :(得分:0)
我认为@Sulthan意味着这样的事情(故意过于明确):
for(int indexA = 0; indexA <= 1; indexA++){
for(int indexB = 0; indexB <= indexA; indexB++){
BOOL flagA = (indexA == 1) ? YES : NO;
BOOL flagB = (indexB == 1) ? YES : NO;
// Use your flags (booleans) here...
}
}
(当然,如果你想避免使用过多的冗余变量,你可以在Objective-C中仅使用int
代替布尔值。)
ADDENDUM:我实际上在Xcode(OSX项目)中执行了“跳转到定义”,部分看起来像这样:
#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif
(USR /包含/ objc / objc.h)
无法在__objc_yes
上“跳转到定义”(提供“未找到符号”)
答案 2 :(得分:0)
我看到的唯一方法是在循环中添加一个中断以逃避无限循环。
另一种可能性是使用简单整数并在counter == 2
for (BOOL flagA = NO; YES; flagA++) {
for (BOOL flagB = NO; YES; flagB++) {
// Do something
if (flagB)
break;
}
if (flagA)
break;
}
答案 3 :(得分:0)
如果您开始使用BOOLs
进行操作,则代替:
for (BOOL flagA = NO; flagA <= YES; flagA++)
for (BOOL flagB = NO; flagB <= flagA; flagB++)
// ...
你应该真的做这件事(虽然这不是你想要的):
for (BOOL flagA = NO; flagA != YES; flagA = !flagA)
for (BOOL flagB = NO; flagB != flagA; flagB = !flagB)
// This is the only safe way to 'iterate' BOOLs
行为(BOOL)++
没有明确定义*因为BOOL
只能是YES
或NO
。你真正应该做的是将你的BOOL
转换为int
,并对其进行迭代,或者完全重构你的循环以使用int
类型。
将BOOL
值转换为ints
的问题正如您所指出的那样,BOOL
对于只有8位信息*的内容是typedef&,因此只有255次迭代才有意义。事实上,在最近的时间里,BOOL
根本不可投射,因为它被定义为编译器内在函数(objc_bool
,它可以具有值__objc_yes
和__objc_no
) 。 __objc_no++
没有任何意义。
TL; DR 我的(强)建议是重构代码,以便迭代整数,并在每次迭代中检查BOOLs
。无论您是否转换BOOL
值,还是重构您的循环都取决于您,但以您指示的方式迭代BOOL
值既不安全又(现在,因此)不受支持。
*在过去几年中,BOOL
的实现细节是显而易见的(即转换为unsigned char)。随着编译器内在函数的出现,细节被隐藏(虽然它们可能是相同的)。它们现在被隐藏的原因是因为你真的不应该依赖它们,阻止人们依赖它们的最简单方法就是将它们完全隐藏在编译器之外。