1

I have a property that I'll call index. I have a mutable array that I'll call array. I'm shocked to find this code throws an index out of bounds exception?

if(index >= [array count]) return;


for(self.item = [array objectAtIndex:index]; index < [array count]; self.item = [array objectAtIndex:index]) {
        index++;
        //do stuffs
    }

However, this variant works:

if(index >= [array count]) return;
while(index < [array count];) {
    self.item = [array objectAtIndex:index];
    index++;
    //do stuffs
}

I expect for loops to operate like so:

for(initialization instructions; condition; next iteration instruction) {...}

I expect the following sequence:

  1. The initialization instructions are executed
  2. Execute code in for loop
  3. Break if condition returns false/0. otherwise, execute next iteration instruction. Then go to 2.

This tells me the for loops do not necessarily check the condition prior to executing the next iteration code (as is in C/C++). So, I'm curious whether there are multiple schools of thought on the order of operations of the for loop. If not, this tells me I have more complicated issues to address.

Thanks.

4

3 回答 3

6

index在第一种情况下,您是否在 for 循环中递增?

for(self.item = [array objectAtIndex:index]; index < [array count]; self.item = [array objectAtIndex:index]) { 
    //do stuffs 
    index++;
} 

如果是这种情况,那么您的语法在您设置的 for 循环的第三部分中被弄乱了,self.item = [array objectAtIndex:index]正是引发异常的地方,因为这部分在比较发生之前index < [array count]执行并让您脱离循环.

你为什么不把你的 for 循环定义为这个?

for(self.item = [array objectAtIndex:index]; index < [array count]; index++) { 
        //do stuffs 
    } 

第一次通过时,您将首先检查 CONDITION,但随后增量器在循环的每次迭代结束时运行。在那一点上它会增加 -> 条件 -> loop_body。

它相当于以下内容:

initialize; 
while(condition) { 
    // do stuffs
    index++;
    LOOP_INCREMENTER; // this is your assignment statement, self.item = [array objectAtIndex:index]; 
} 
于 2012-04-28T05:08:51.707 回答
2

您对for循环如何工作的期望是不正确的。

for(initialization instructions; condition; next iteration instruction) {...}

顺序如下:

1. initialization instructions
2. test condition, if condition is true do the following:
    2a. execute loop body
    2b. execute next iteration instruction
    2c. goto step 2

所以问题是,当index == ([array count] - 1)循环体执行评估index++时,设置index == [array count]

当循环体完成时,“下一次迭代指令”将尝试评估[array objectAtIndex:index]index大。请记住,这一步发生在循环体执行之后和条件测试之前。这就是 C 一直以来处理for循环的方式。

请尝试以下循环:

for(; index < [array count]; ++index) {
    self.item = [array objectAtIndex:index];

    //do stuffs
}

当然,您可能还需要调整循环体区域中index任何现有的使用。//do stuffs

于 2012-04-28T06:43:24.123 回答
-1

你写的代码不是你所期望的。

要遍历数组,您应该考虑 for-in 循环:

for (MyObject* obj in array) {
   // do something with obj
   self.item = obj;
}

您使用的 for 循环在几个方面都是错误的,并且(非常)明显为什么您超出了数组的限制:

在最后一个有效循环中,您正在增加索引,然后 for 指令将执行 for 的第三个参数:

self.item = [array objectAtIndex:index]

在那一刻,索引大于数组边界,因为条件(for指令的第二个参数)将在之后执行。

于 2012-04-28T07:26:41.437 回答