In (Objective-)C(++) the statements while(...) { ... }, for(...) { ... }, switch(...) { ...} etc. contain a single block statement (if (...) { ... } else { ... } contains two). The scope of declarations within a block is just that block, and it is an error to declare the same variable twice within a block.
The block of a switch contains a number of case ...: labels - labels do not delimit blocks, they are just points within a block that control flow can jump to. This makes switch statements in C different than in some other languages where each branch is independent (as the two blocks in an if/else are independent in C). A C switch is just a "computed goto" into a single block. This is why the break; statement exists, without it control flow just continues from one "branch" to the next.
Another consequence of this is that different branches cannot declare the same variable names, unlike for if/else statements.
Finally only statements and not declarations can be labelled, and as a case ...: is a form of label there cannot be a declaration immediately following one - so you cannot start a "branch" with a declaration.
If the variables you wish to declare within a branch are for use only in that branch (as they would be if declared in either of the blocks of an if/else) then you can solve all the problems by enclosing the branch in braces, { ... }, to make it into a block statement - blocks can be labelled and can contain local declarations. E.g. something along the lines of:
switch (expr)
{
case 1:
{
NSString *var;
// use var
break;
}
case 2:
{
NSNumber *var;
// use var
break;
}
...
}
// no var here
If you are assigning to variables which you need to use after the switch then you must declare them before the switch, as the body of a switch is a block and hence a local declaration scope. E.g. something along the lines of:
NSString *var = nil;
switch (expr)
{
case 1:
...
var = ...;
break;
case 2:
...
var = ...;
break;
...
}
// use var here
HTH