"Switch" Statement in Obj-C

Discussion in 'Mac Programming' started by satyam90, Dec 19, 2007.

  1. satyam90 macrumors regular

    satyam90

    Joined:
    Jul 30, 2007
    Location:
    Bangalore, India
    #1
    Hi, I am using Cocoa with XCode for Objective-C project.
    I am using "Switch" statement for strings which is giving compile error. But "Switch" is working fine in windows for strings......For example the following code for Objective-C is giving errrors:
    Code:
    switch(name)
    {
       case @"Apple":
               .......
               break;
       case @"Grapes":
             .......
             break;
       default:
             break;
    }
    
    Can anyone tell me why it is not working.
    Ofcourse, the solution for this is to use "if-else", but how to get it done using switch.
     
  2. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
  3. gekko513 macrumors 603

    gekko513

    Joined:
    Oct 16, 2003
    #3
    If I'm not mistaken it's because Obj-C strings are objects and you can't use switch on general objects. It's not really harder to copy and paste else-if, and the performance isn't that much different either, so just go for else-if.
     
  4. Soulstorm macrumors 68000

    Soulstorm

    Joined:
    Feb 1, 2005
    #4
    The error you have is not a language depended one, but a logical one. Switch statements can only be used with integers. An NSString class is a pointer to an allocated chunk of memory that holds universal characters, not an integer. Use only integers with the switch statement, in any C-like language.
     
  5. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    Off-track/off topic:

    NSStrings are immutable and (iirc) there is a compiler option to have NSString use the same instance for NSStrings with the same value. So in this case we would know that the memory address of every @"Apple" was the same. With a bit of compiler magic could this not be used to enable switch statements on NSStrings (not NSMutableStrings)? Clearly there is an issue that the memory address is not constant but still I would have thought that could be sorted at ling time.
     
  6. Soulstorm macrumors 68000

    Soulstorm

    Joined:
    Feb 1, 2005
    #6
    Why would we want to do that? That would add an additional overhead, since each time a string is created the compiler will test the availability of that value in each string already created.
     
  7. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #7
    Uses less memory and if the string exists it could actually be cheaper to create the object. It may only be true for statically defined strings like @"Apple" which would make sense: in this case it is a pure compiler optimisation.

    For runtime NSStrings would depend on whether, on average, the cost of hashing a string and looking up a hashtable is cheaper than creating an object or not.
     
  8. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #8
    Using which language and compiler?
     
  9. iSee macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #9
    Neat idea, but usually that kind of compiler option only combines string literals, not ones created by other means. So if @"Apple" appeared 100 times in your source code, with this option set only one would actually exist, and all places where it was used would point to that same one. However, if you created a string through some other means it wouldn't. For example, if you created a string by taking the first five characters of @"Apple rules!" it would NOT be the same instance as the @"Apple" literals, so they'd have different pointer values (I never looked in to gcc's option, but I'd be suprised if it was different.)

    Also, to the OP: you can't do a switch on string values in C, C++, or Objective-C. I think C# allows this. Whether you're running your compiler on Windows or not makes no difference. (If your C/C++/Objective-C compiler is allowing it, it is a bug in the compiler (and it's probably comparing pointer values, not doing a string comparison).
     
  10. GeeYouEye macrumors 68000

    GeeYouEye

    Joined:
    Dec 9, 2001
    Location:
    State of Denial
    #10
    There are many ways to get if-else-if...else semantics in C/Obj-C. Don't discount them.
    Code:
    id result = [name isEqualToString:@"Apple"]?[something doStuff]:[name isEqualToString:@"Grapes"]?[somethingElse doThings]:nil;
    And you can add whatever whitespace you want to make it look kind of like a switch statement.
     
  11. iSee macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #11
    You could even use if-else if-else constructs!
     
  12. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #12
    Yeah, I don't see how if-else statements are really any worse than a switch. You type a little more on each check, but you don't need all the break statements.

    Code:
    if ([name isEqualToString:@"Apple"]) {
    	...
    } else if ([name isEqualToString:@"Grapes"]) {
    	...
    } else {
    	...
    }
     
  13. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #13
    Switch statements are more efficient and faster, and I think they are easier to read but obviously they don't work for objects.

    But often you can avoid multiple if-else statements when comparing objects and store results in a collection, and then lookup those objects in the collection (NSArray's indexOfObject: or NSDictionary's objectForKey:).
     
  14. iSee macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #14
    I read an interesting paper comparing the efficiency of various methods of implementing a string map (each entry maps a string to some other value--that is, you can look up a value by string).

    Their conclusion was that, in general, for small numbers of entries (<15-20), the most efficient method to look up a value was to compare it to each string, one after another, until a match was found. The reason was that the various types of hash tables and trees introduced extra overhead. The number of entries had to be relatively large before the time savings was greater than the overhead. They used carefully optimized hash tables and trees.

    So, you can feel pretty comfortable using if, else-if, else constructs to match small numbers of strings. This is less true if many of the strings being compared begin with long sequences of identical characters, but in this case it is easy to optimize (when using string constants) by using nested if-else constructs.

    A good compiler for a language that does allow switch statements on strings would use a linear search when there are a small number of cases, and use some kind if hash table for switch statements with larger numbers of cases.
     
  15. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #15
    Instead of carefully optimized tables or trees, you could just do a switch on the first character of the string first. For 10-15 entries, you will often have one or no choices left, and you only need to check whether you have a match. For 100-200 entries, you will usually not have more than 10 choices left, so you can do the linear search again, or switch depending on the next character.
     
  16. Krevnik macrumors 68030

    Krevnik

    Joined:
    Sep 8, 2003
    #16
    I assume you are writing in a .NET language on Windows, maybe C#? .NET treats strings differently than most C-like languages, as a core data type rather than an object (although technically it is an object as well). It has a lot of custom syntax around strings that most languages don't.
     

Share This Page