0

I've got a prepareForSegue method in two different VCs. One uses an if statement, while the other is intended to use a switch. The code is virtually identical, except for names.

This one works fine:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
        NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    if ([[segue identifier] isEqualToString:@"addActivity"])
    {
        UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
        AddActivityViewController *aavc = (AddActivityViewController *)navController.topViewController;
        aavc.delegate = self;
        ListActivity *addedActivity = (ListActivity *)[ListActivity MR_createInContext:localContext];
        aavc.thisActivity = addedActivity;
    }

This one gives me two warnings. On the first line, I get an "Expected expression" warning. On the second line, I get "Use of undeclared identifier 'NavController'.

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    [SearchSpecs MR_truncateAllInContext:localContext];
    [localContext MR_saveToPersistentStoreAndWait];

    switch ([sender tag])
    {
        case aVsAButton_tag:
            UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
            AvsAViewController *aVSaVC = (AvsAViewController *)navController.topViewController;
            aVSaVC.delegate = self;
            SearchSpecs *thisSpec = (SearchSpecs *)[SearchSpecs MR_createInContext:localContext];
            aVSaVC.currentSpec = thisSpec;

            break;

        default:
            break;
    }

}

Can someone please point out my mistake?

Thanks!

Edit:

The problem was fixed by all the answers given, and many thanks for all!

Here is my new code:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    [SearchSpecs MR_truncateAllInContext:localContext];
    [localContext MR_saveToPersistentStoreAndWait];

    switch ([sender tag])
    {
        case aVsAButton_tag:
        {
            UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
            AvsAViewController *aVSaVC = (AvsAViewController *)navController.topViewController;
            aVSaVC.delegate = self;
            SearchSpecs *thisSpec = (SearchSpecs *)[SearchSpecs MR_createInContext:localContext];
            aVSaVC.currentSpec = thisSpec;
        }
            break;

        default:
            break;
    }

}

When I added the semi-colon per the suggestion of the third answer, I got the warning that "Switch case is in protected scope" at the default: line. However, when I enclosed the case code in curly brackets, all problems evaporated. Very good thing for me to remember!

I would green-check all answers, but since they all arrived about simultaneously, I hope no one will be offended if I accept the top one. +1 for all, and thanks again!

rattletrap99
  • 1,469
  • 2
  • 17
  • 36

3 Answers3

3

To solve the second error, try adding braces in your switch-case to define a context to the variables:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    [SearchSpecs MR_truncateAllInContext:localContext];
    [localContext MR_saveToPersistentStoreAndWait];

    switch ([sender tag])
    {
        case aVsAButton_tag:
            {
                UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
                AvsAViewController *aVSaVC = (AvsAViewController *)navController.topViewController;
                aVSaVC.delegate = self;
                SearchSpecs *thisSpec = (SearchSpecs *)[SearchSpecs MR_createInContext:localContext];
                aVSaVC.currentSpec = thisSpec;
            }
            break;

        default:
            break;
    }

}
Guilherme
  • 7,839
  • 9
  • 56
  • 99
3

In C/Objective-C, you cannot declare variables in a switch statement like that. If you want to declare variables for use in a specific case of a switch statement, you can put all the code for that case in a statement block:

switch ([sender tag])
{
    case aVsAButton_tag:
    {
        UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
        AvsAViewController *aVSaVC = (AvsAViewController *)navController.topViewController;
        aVSaVC.delegate = self;
        SearchSpecs *thisSpec = (SearchSpecs *)[SearchSpecs MR_createInContext:localContext];
        aVSaVC.currentSpec = thisSpec;
    }
        break;

    default:
        break;
}
Mike Mertsock
  • 11,825
  • 7
  • 42
  • 75
  • 1
    [Here is a good explanation](http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement) of why you need the brackets when you’re trying to do something like this. – bdesham Feb 18 '14 at 18:37
  • Also in C++ this is the case – Jeef Feb 18 '14 at 18:37
3

There are two separate problems here.

You can declare a variable in C/Objective-C in a switch-statement (without the need for an additional { ... } scope), but not immediately following a label. To solve this problem it is sufficient to insert a semicolon after the label:

switch (i) {
    case 0: ;
        int i;
        // ...
        break;

    default:
        break;
}

Only if you declare Objective-C objects and compile with ARC, then you have to introduce an additional scope:

switch (i) {
    case 0: {
        NSObject *obj;
        // ...
        } break;

    default:
        break;
}

The reason is that the ARC compiler needs to know the precise lifetime of the object.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382