1

这是几行代码... 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 :)

4

3 回答 3

5

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

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

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


1大多数现代计算机中用于表示负数的-12 -s 补码表示的值是完全由 1 组成的二进制数。当这个数字被重新解释为一个无符号的 32 位值时,它变成2^32-1.

于 2012-08-29T15:29:25.120 回答
2

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

另请参见unsigned long 0 < -1?

于 2012-08-29T15:30:53.457 回答
0

这是一个很长的镜头......但试着像这样写你的条件:

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

也许问题是编译器像这样对它进行分组

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

(0 < 0) 返回false(0),然后减1,一直停留在-1,和0不同,所以返回true

于 2012-08-29T15:28:23.653 回答