0

I have a loop like this:

label: for(X *y in z)
    {
        switch(y.num)
        {
          case ShouldDoSomething:
            [self somethingWithX:y];
            break;
          case ShouldStopNow:
            y = [self valWhenStopped];
            break label;
        }
        [val append y];
    }

Of course, since Objective-C does not support loop labeling (at least, when I try, it throws a compile error saying Expected ';' after break statement), this doesn't work. Is there a way I can break a loop using a switch case in Objective-C? If not, what's a best practice with the same effect?

Ky -
  • 30,724
  • 51
  • 192
  • 308
  • 1
    you can use "`goto` + label", [but do you really want to do it](http://stackoverflow.com/questions/1764354/how-can-i-use-goto-in-a-switch-statement-in-objective-c)? – Michael Dautermann Jun 26 '15 at 18:23

3 Answers3

4

A solution is to put the whole expression into a method and exit the switch statement with return.

- (void)checkSomething:(id)object
{
  for(X *y in object)
  {
    switch(y.num)
    {
      case ShouldDoSomething:
        something();
        break;
      case ShouldStopNow:
        return;
        break;
    }
    somethingElse();
  }
}

Another solution is using a boolean flag

for(X *y in Z)
  {
    BOOL willExitLoop = false;
    switch(y.num)
    {
      case ShouldDoSomething:
        something();
        break;
      case ShouldStopNow:
        willExitLoop = true;
        break;
    }
    if (willExitLoop) break;
    somethingElse();
  }
vadian
  • 274,689
  • 30
  • 353
  • 361
  • This seems like two solutions in one answer. Perhaps split them into two answers? – Ky - Jun 26 '15 at 18:29
  • I changed the formatting of the answer to make it clearer – vadian Jun 26 '15 at 18:32
  • 1
    You still center your answer around using a method and return, but don't provide code. And then you somewhat passively say there's another solution, and provide code for that. – Ky - Jun 26 '15 at 18:33
  • I edited the code to reflect your main answer. I hope you don't mind. – Ky - Jun 26 '15 at 21:48
  • and I edited my post to provide code for the first solution and I changed the code of the second solution because it didn't work as you requested – vadian Jun 27 '15 at 04:42
1

You can also use a flag:

for(...)
{
    BOOL stop = NO ;
    switch(...)
    {
        case x:
            break ;
        case y:
            stop = YES ;
            break ;
    }
    if ( stop ) { break ; }
    somethingElse();
}
nielsbot
  • 15,922
  • 4
  • 48
  • 73
1

I think you are looking for continue:

for(X *y in Z)
{
switch(y.num)
{
    case ShouldDoSomething:
        something();
        break;
    case ShouldStopNow:
        continue;  //-- this will break the switch and reenter the for loop with the next element
}
somethingElse();
}
sergio
  • 68,819
  • 11
  • 102
  • 123
  • Except that will continue looping, perhaps 1 or more times. I wish to stop looping altogether. – Ky - Jun 26 '15 at 21:43