在Objective-C中循环BOOL

时间:2015-02-23 09:24:28

标签: ios objective-c for-loop boolean

像这样遍历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的使用?

4 个答案:

答案 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位,它也不能具有除01之外的任何其他值。为什么?因为bool a = 3(bool等于运算符)将3转换为bool值,true1

因此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循环
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只能是YESNO。你真正应该做的是将你的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)。随着编译器内在函数的出现,细节被隐藏(虽然它们可能是相同的)。它们现在被隐藏的原因是因为你真的不应该依赖它们,阻止人们依赖它们的最简单方法就是将它们完全隐藏在编译器之外。