Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

satyam90

macrumors regular
Original poster
Jul 30, 2007
242
0
Bangalore, India
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.
 
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.
 
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.

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.
 
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.
 
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.

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.
 
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.

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.
 
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......

Using which language and compiler?
 
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.

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).
 
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.
 
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.

You could even use if-else if-else constructs!
 
You could even use if-else if-else constructs!
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 {
	...
}
 
Yeah, I don't see how if-else statements are really any worse than a switch.

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:).
 
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.
 
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.

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.
 
But "Switch" is working fine in windows for strings......

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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.