Objective-C可以打开NSString吗?

Jam*_*sev 164 objective-c switch-statement

有没有更聪明的方法来重写这个?

if ([cardName isEqualToString:@"Six"]) {
    [self setValue:6];
} else if ([cardName isEqualToString:@"Seven"]) {
    [self setValue:7];
} else if ([cardName isEqualToString:@"Eight"]) {
    [self setValue:8];
} else if ([cardName isEqualToString:@"Nine"]) {
    [self setValue:9];
} 
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 146

不幸的是他们不能.这是切换语句中最好和最受追捧的利用之一,所以希望他们跳上(现在)Java(和其他人)的潮流!

如果您正在使用卡名称,可能会为每个卡对象分配一个整数值并打开它.或者也许是一个枚举,它被认为是一个数字,因此可以接通.

例如

typedef enum{
  Ace, Two, Three, Four, Five ... Jack, Queen, King

} CardType;
Run Code Online (Sandbox Code Playgroud)

通过这种方式,Ace将等于案例0,两个作为案例1,等等.

  • @abbood有关枚举的更多信息,请参阅Mattt Thompson的帖子[NS_ENUM&NS_OPTIONS](http://www.nshipster.com/ns_enum-ns_options/). (4认同)
  • 这是应该做的唯一方法. (2认同)

Gra*_*rks 119

您可以设置块的字典,如下所示:

NSString *lookup = @"Hearts"; // The value you want to switch on

typedef void (^CaseBlock)();

// Squint and this looks like a proper switch!
NSDictionary *d = @{
    @"Diamonds": 
    ^{ 
        NSLog(@"Riches!"); 
    },
    @"Hearts":
    ^{ 
        self.hearts++;
        NSLog(@"Hearts!"); 
    },
    @"Clubs":
    ^{ 
        NSLog(@"Late night coding > late night dancing"); 
    },
    @"Spades":
    ^{ 
        NSLog(@"I'm digging it"); 
    }
};

((CaseBlock)d[lookup])(); // invoke the correct block of code
Run Code Online (Sandbox Code Playgroud)

要拥有"默认"部分,请将最后一行替换为:

CaseBlock c = d[lookup];
if (c) c(); else { NSLog(@"Joker"); }
Run Code Online (Sandbox Code Playgroud)

希望Apple能够教授"切换"一些新技巧.

  • 我不知道这是不是真的很讨厌或真的很酷.从来没想过会这样做,谢谢. (33认同)
  • 虽然我们正在做这样奇怪的事情,为什么不创建自己的类来包装NSDictionary充满NSString键的块对象,然后为默认情况提供另一个块?你甚至可以让它支持下标符号. (2认同)
  • 在幕后,这是C#处理大型switch语句的方式。 (2认同)

sbo*_*sky 77

对我来说,一个很简单的方法:

NSString *theString = @"item3";   // The one we want to switch on
NSArray *items = @[@"item1", @"item2", @"item3"];
int item = [items indexOfObject:theString];
switch (item) {
    case 0:
       // Item 1
       break;
    case 1:
       // Item 2
       break;
    case 2:
       // Item 3
       break;
    default:
       break;
}
Run Code Online (Sandbox Code Playgroud)

  • 我不会将这个hack与JS开关进行比较.如果下一个程序员在item1和item2之间添加项目会怎样?引入错误的可能性太大 (4认同)

ugh*_*fhw 11

不幸的是,switch语句只能用于原始类型.但是,您确实有一些使用集合的选项.

可能最好的选择是将每个值存储为NSDictionary中的条目.

NSDictionary *stringToNumber = [NSDictionary dictionaryWithObjectsAndKeys:
                                              [NSNumber numberWithInt:6],@"Six",
                                              [NSNumber numberWithInt:7],@"Seven",
                                              [NSNumber numberWithInt:8],@"Eight",
                                              [NSNumber numberWithInt:9],@"Nine",
                                              nil];
NSNumber *number = [stringToNumber objectForKey:cardName];
if(number) [self setValue:[number intValue]];
Run Code Online (Sandbox Code Playgroud)


小智 8

有点晚了,但对于未来的任何人,我都可以让这个为我工作

#define CASE(str) if ([__s__ isEqualToString:(str)])
#define SWITCH(s) for (NSString *__s__ = (s); ; )
#define DEFAULT
Run Code Online (Sandbox Code Playgroud)


Dav*_*ong 6

这是更聪明的写作方式.这是NSNumberFormatter"拼写风格"中使用:

NSString *cardName = ...;

NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterSpellOutStyle];
NSNumber *n = [nf numberFromString:[cardName lowercaseString]];
[self setValue:[n intValue]];
[nf release];
Run Code Online (Sandbox Code Playgroud)

请注意,数字格式化程序希望字符串是小写的,因此我们必须在将其传递给格式化程序之前自己执行此操作.


Cal*_*leb 5

还有其他方法可以做到这一点,但switch不是其中之一.

如果您只有几个字符串,如您的示例所示,您拥有的代码就可以了.如果您有很多情况,可以将字符串存储为字典中的键并查找相应的值:

NSDictionary *cases = @{@"Six" : @6,
                        @"Seven" : @7,
                        //...
                       };

NSNumber *value = [cases objectForKey:cardName];
if (value != nil) {
    [self setValue:[value intValue]];
}
Run Code Online (Sandbox Code Playgroud)