条件似乎错误...为什么它是真的?

时间:2012-08-29 15:24:02

标签: objective-c

这里有几行代码... currentPage是一个NSInteger,imageViewHolder是一个NSMutableArray。

    NSLog(@"currentPage: %d, imageViewHolderCount: %d", currentPage, [imageViewHolder count]);
    if(currentPage < [imageViewHolder count] - 1)       
    {
        NSLog(@"%d < %d - 1", currentPage, [imageViewHolder count]);
        tempView = [imageViewHolder objectAtIndex:currentPage + 1];
        NSLog(@"doesn't get here, crashed.");   //this doesn't get logged because of crash.

        //do other stuff here
    }

由于索引越界,我在“tempView = ...”行崩溃。这是我得到的输出:

currentPage: 0, imageViewHolderCount: 0
0 < 0 - 1
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array'
*** First throw call stack:
(0x339bd88f 0x324af259 0x339069db 0x48f1b 0x48c1b 0x35603a85 0x35603409 0x35602c57 0x35716b0f 0x3560424d 0x4abfb 0x324ab175 0x43f77 0x45b91 0x479a7 0x36bff 0x285ed 0x35604ecb 0x32935933 0x33991a33 0x33991699 0x3399026f 0x339134a5 0x3391336d 0x32e91439 0x35608e7d 0xfa01 0xf9c0)

我确定我遗漏了一些明显的东西......为什么我的if语句被评估为真?我很确定0实际上大于-1:)

3 个答案:

答案 0 :(得分:5)

问题是count无符号类型。当您从无符号零中减去1时,最终得到一个非常大的正数 1 而不是-1

将条件替换为使用加法的等效表达式以避免问题:

if((currentPage+1) < [imageViewHolder count]) ...

<小时/> 1 在大多数现代计算机中用于表示否定的2-s complement表示中的-1的值是完全由1组成的二进制数。当此数字被重新解释为无符号32位值时,它变为2^32-1

答案 1 :(得分:2)

是的,但0远小于MAX_INT。你正在使用无符号整数(我必须仔细检查关于它是否被定义为MAX_INT的标准,或者恰好是MAX_INT的未定义行为,但在任何一种情况下它都不是你的意思)。我怀疑如果你查看你的编译器输出,就会发出这种效果的警告(绝不允许在ObjC代码中发出任何警告)。

另见unsigned long 0 < -1?

答案 2 :(得分:0)

这是一个很长的镜头...但尝试写下这样的条件:

(currentPage < ([imageViewHolder count] - 1))

也许问题是编译器正在将它分组为

((currentPage < [imageViewHolder count]) - 1)

(0 <0)返回false(0),然后减去1,并保持在-1,这与0不同,因此返回true