我怎样才能摆脱Objective-C中的两个嵌套for循环?

我有两个for循环嵌套像这样:

for(...) { for(...) { } } 

我知道有一个断言。 但是,如果它打破了两个循环,或者只是它被调用的那个,我感到困惑。 当我看到迭代次数没有意义的时候,我需要立即打破这两个问题。

打破了一个循环,但是你可以添加一个检查外部循环,当内部rest时破坏。

 bool dobreak = false; for ( ..; !dobreak && ..; .. ) { for ( ... ) { if (...) { dobreak = true; break; } } } 

如果使用goto简化了代码,那么这将是适当的。

 for (;;) { for (;;) { break; /* breaks inner loop */ } for (;;) { goto outer; /* breaks outer loop */ } } outer:; 

break语句只会让你离开最内层的循环。 如果你不想在代码,内存和一个专用状态variables的性能上增加开销,我build议将代码重构成它自己的函数或方法,并使用return来退出所有的循环:

 void do_lots_of_work(void) { int i, j; for(i=0; i<10 ; i++) { for(j=0;j< 10; j++) { .. .. if(disaster_struck()) return; /* Gets us out of the loops, and the function too. */ } } } 

除了已经提到的标志variables或转到,你可以抛出一个Objective-Cexception:

 @try { for() { for() { @throw ... } } } @catch{ ... } 

其他人提到如何设置一个标志或使用goto ,但是我build议重构你的代码,这样内部循环就变成了一个单独的方法。 然后,该方法可以返回一些标志,以指示外部循环应该break 。 如果你适当地命名你的方法,这是更可读。

 for (int i = 0; i < 10; i++) { if (timeToStop(i)) break; } -(bool) timeToStop: (int) i { for (int j = 0; j < 10; j++) { if (somethingBadHappens) return true; } return false; } 

伪代码,没有testing,但你明白了。

break语句只会在父循环的作用域中跳出循环。 如果你想打破第二个循环,你可以使用两个循环范围内的布尔variables

 bool isTerminated = false; for (...) { if (!isTerminated) { for(...) { ... isTerminated = true; break; } } else { break; } } 

rest之前更改顶部循环的计数器

 for(i=0; i<10 ; i++) for(j=0;j< 10; j++){ .. .. i = 10; break; } 

可能最简单的方法是使用“标志”variables

 for(i=0; i<10 && (done==false); i++) for(j=0;j< 10; j++){ .. .. if(...){done=true; break;} } 

另一个解决方法是在一个函数中分解第二个循环:

 int i; for(i=0; i<10 ; i++){ if !innerLoop(i) { break; } } bool innerLoop(int i) int j; for(j=0;j< 10; j++){ doSomthing(i,j); if(endcondtion){ return false; } } } 

如果从一组嵌套循环中执行一个中断,则只有最后一个中断循环被终止。 (就像标准C一样)

break语句打破了最内层的循环。 需要额外的testing和中断声明来突破外部循环。

完全像最后一个,一般是这样的:

 for(i=0;i<a;i++){ for(j=0;j<a;j++){ if(Something_goes_wrong){ i=a; break; } } } 

只是为了微笑,如何改变这个真/假检查到一个方法和使用return语句:

 - (bool) checkTrueFalse: parameters{ for ( ...) { for ( ... ) { if (...) { return true; } } } return false; }