"switching" NSStrings

maccatalan

Registered
Hi.

You probably know the "swtitch"/"case" C control structure. It works with the basics data types : int, char, ... but not with NSString objects nor any non basic type.

Do you know a way to make it to work ? (without converting the NSString to a char*)

thank you,
that's not important, just curiosity (I already found a pretty good way to solve my problem with the simple use of a NSDictionary).
Pierre
 
there might be some way to do it, but I really encourage you not to try. the thing with switches is that they rely on equality, and that is fine with primitive data types (int, float, char, pointers). when it comes to objects, however, no two are equal (in the "==" sense), unless they are the same, for example to variables referencing the same object. the same is true for pointers, but more obvious in that case.

objects (or rather, object references) can only be checked for equality (not in the "==" sense) by using the -isEqual: method, which does not play along with switch/case...

so if you want to do switch/case-ing with object, do if-else-if-else instead:

Code:
if ( [reference isEqual:obj1] ) {
   // this is a case
} else if ( [reference isEqual:obj2] ) {
   // this is a case
} else {
   // this is the default case
}

This kind of structure is equal to a switch/case structure anyway.

Hope this helps.

theo
 
it works, but it isn't as neat as switch ... you're obliged to repeat the [reference isEqualTo:***] :( ... That's what I would like to avoid and that's the purpose of switch/case.

The best solution, from my point of view, is to use a NSDictionary :



- (void) myFunction: (NSString *) clef {
NSDictionary *dico = [NSDictionary dictionaryWithContentsOfFile:mad:"myPath"];

switch ([[dico objectForKey:clef] intValue]) {
case 69 : instr1; ... ; break;
case ...
}

}


(NB:In my "case" using a file is better)

thank you. ;)
 
not so much anymore, but it's my favourite too. I had one for years, I ran photoshop 4 on it, without a problem... then I switched to a G3/300... quite a leap in speed, but I still have the LC475... now I'm on a dual G4/450 and moving on to a TiBook/667.

It wasn't actually a 475, really, it was a LC (the first version) with a pirate upgrade to a 475-motherboard and as much RAM that I was able to jam in to the board. Cool machine. A shame that it can't run OSX... think it can run NetBSD, though... maybe I should try.

sorry, but I think your code is dead ugly =), I vote for the if-else-if path...

theo
 
Originally posted by iconara
sorry, but I think your code is dead ugly =), I vote for the if-else-if path...

maybe ugly but worky. :)
I'm making a little runtime interpreter. So I create a plist file with the description of each command and converting this file to a NSDictionnary I can do exactly what I want with some "special" commands then scripted case by case, the others, scripted in default, executing a little auxiliary program.

I don't know if I'm very clear (I don't really speak english ... just try to) but ... well, we can sum this up saying that it works for me. I just regret that the switch/case structure is so limited ... (even in C++) ...

see you,
Pierre
 
switch/case is one way of building a jump table--it requires the targets to be compile-time constants (for obvious reasons of non-mutable code).

Another way to build a jump table, more suited to string matches is the use of associative arrays indexed by strings (isn't this NSDictionary?), containing references/pointers to functions to be called. This approach is very popular in recursive descent parsers, but tends to be somewhat unreadable, as target bodies are all over the place.

Another, and slowest yet, is the use of if/else if chains.
 
I thought that:


Code:
if ( reference == c1 ) {
   // case1
} else if ( reference == c2 ) {
   // case2
} else {
   // default
}


would compile into roughly the same as

Code:
switch ( reference ) {
    case c1: 
      // case1
      break;
    case c2: 
      // case2
      break;
    default: 
     // default;
}

due to compiler optimisations. althought it wouldn't be the same if the if-tests were method calls... but in the case of constants?

but I have been wrong before =)

theo
 
optimizing for a very non-common case better expressed as a switch construct.

Don't hold your breath.

Besides, you would lose the fallthrough feature of switch in any case.

If you really want to know how does a compiler build a switch jumptable, examine the generated assembly. The best test example would have several series of ascending cases; in this case, in usual implementation the variable is compared against the series, the value of the first case in series subtracted, and the rest used as an offset into jump instruction addresses.

Things really get non-optimal if cases are laid out out of order (remeber, switch has that fallthrough feature).

BTW, switch works only on atomic integral types (i.e. it does not work with floating point, and it does not work well with pointers)
 
Back
Top