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.
 

gekko513

macrumors 603
Oct 16, 2003
6,301
1
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.
 

Soulstorm

macrumors 68000
Feb 1, 2005
1,887
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.

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.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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.
 

Soulstorm

macrumors 68000
Feb 1, 2005
1,887
1
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.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
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?
 

iSee

macrumors 68040
Oct 25, 2004
3,540
272
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).
 

GeeYouEye

macrumors 68000
Dec 9, 2001
1,669
10
State of Denial
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.
 

iSee

macrumors 68040
Oct 25, 2004
3,540
272
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!
 

HiRez

macrumors 603
Jan 6, 2004
6,265
2,630
Western US
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 {
	...
}
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
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:).
 

iSee

macrumors 68040
Oct 25, 2004
3,540
272
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.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
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.
 

Krevnik

macrumors 601
Sep 8, 2003
4,101
1,312
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.