如何有效地将命令名称映射到操作中?

时间:2012-07-19 08:15:32

标签: objective-c ios

我有一个包含数百个命令的命令列表,需要经常调用此命令列表。像:

if([command isEqualToString:"openPage1"]){
  open page 1
}else if ([command isEqualToString:"jumpToPage4"]){
  get param1 and param2
  jump to page 4
}else if ([command isEqualToString:"backToPage10"]){
  get param1
  back to page 10
}....

由于有数百个命令并经常调用,所以我不会想到" if else"是个好方法......

哪种算法更快更有效率?

1 个答案:

答案 0 :(得分:4)

您可以使用NSDictionary将命令名称直接映射到代码,无论是选择器,调用还是块。类似的东西:

NSMutableDictionary *actions = [NSMutableDictionary dictionary];
[actions setObject:^{
    [self getParam1];
    [self getParam2];
    [self navigateSomewhere];
} forKey:@"openPage1"];

然后:

dispatch_block_t action = [actions objectForKey:command];
if (action) {
    action();
} else {
    /* handle unknown command */
}

当然字典只会初始化一次,然后缓存。如果操作始终是相同的调用,只需使用不同的参数,则可以将命令名称直接映射到参数:

// setup:
NSDictionary *commandsToPages = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:1], @"command1",
    /* more mappings */,
    nil];
// …and later:
NSNumber *pageNumber = [commandsToPages objectForKey:commandName];
[self displayPage:[pageNumber intValue]];

如果可能的话,还可以选择解析命令名称来提取页码。


PS。从LLVM 4.1(?)开始,您还可以使用简写文字语法来创建动作词典,这使得它在眼睛上更容易:

NSDictionary *actions = @{
    @"command1" : ^{
        …
    },
    @"command2" : ^{
        …
    },
};

请注意,即使是第二个命令块之后的尾随逗号也可以。