views:

84

answers:

2

Is there a better way in Objective-C to do:

if ([elementName isEqual:@"one"]){
   // do some stuff
}
else if ([elementName isEqual:@"two"]]{
   // do more stuff
}
else if ([elementName isEqual:@"three"]]{
   // do more stuff
}

ideally, I would like something like:


//BAD CODE, NOT REAL!!!

  switchString(elementName){
     @"one":
        // do stuff
        break;
     @"two":
        // do more stuff
        break;
     @"three":
        // do more stuff
        break;
    }
+1  A: 

No you did that correctly except I would use:

[elementName isEqualToString:@"one"]
Ben
+7  A: 

A little bit more concise

NSArray* array = [NSArray arrayWithObjects:@"one",@"two",@"three",nil];

int index = [array indexOfObject:elementName];

switch (index) {
    case 0:
        break;
    ...
    default:
        // -1 would be not fount      
}

another, a little bit more complicated way would be to store the strings and NSInvocations in a dictionary and the pull the invocation out using your element name as a key. I would do that if the "do stuff" part is more that a couple of lines in scope

Harald Scheirich
very cool way of doing this! And as a bonus, I didn't know about NSInvocations which looks perfect!!!
Alan
`indexOfObjectIdenticalTo:` will only work if `elementName` is a constant string (i.e., from a string literal) from the same implementation file. If it was entered by the user, copied to or from NSMutableString at any point, or obtained from the framework (e.g., from `NSLocalizedString`), it will not be identical to (the same object as) any of the constant strings in the array. The correct message is `indexOfObject:`.
Peter Hosey
Thanks, did not look that up right ...
Harald Scheirich
An alternative is to use blocks: `void (^action)() = [[NSDictionary dictionaryWithObjectsAndKeys:^{ /* do thing one */ }, @"one", ^{ /* do thing two */ }, @"two", nil] objectForKey:elementName]; if (action) action();` Not hugely elegant, but simpler than `NSInvocation`.
Ahruman