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

Objective c 如何有效地将命令名映射到操作中?,objective-c,ios,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

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

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”是一个好方法


哪种算法更快、效率更高?

您可以使用一个
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" : ^{
        …
    },
};

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

您可以有一个
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" : ^{
        …
    },
};

请注意,即使是第二个命令块后面的逗号也有效。

所有这些命令是否都具有相同数量的参数和相同的返回值?如果是这样,您可以使用字典查找。所有这些命令是否具有相同数量的参数和相同的返回值?如果是这样,您可以使用字典查找。但只有在所有方法都没有参数且没有返回类型的情况下,这才有效。然而,这是一个很好的方法,也是我使用的方法。这是我在评论中开始写的,但现在没有必要完成它,你更快了。:)感谢您的快速回复,我更新了我的问题,情况有点复杂,命令不仅仅是打开页面,在命令判断之后,有些命令有参数,有些没有…但您仍然可以将所有操作代码粘贴到一个块中
^{get param;jump Anywhere;}
如果没有,为什么?是的,我看到了您的字典方式,这对我很好,我正在研究nsdictionary如何与block一起工作,很高兴您有一些教程。但是,只有在所有方法都没有参数和返回类型的情况下,这才可以很好地工作。然而,这是一个很好的方法,也是我使用的方法。这是我在评论中开始写的,但现在没有必要完成它,你更快了。:)感谢您的快速回复,我更新了我的问题,情况有点复杂,命令不仅仅是打开页面,在命令判断之后,有些命令有参数,有些没有…但您仍然可以将所有操作代码粘贴到一个块中
^{get param;jump where;}
如果没有,为什么?是的,我看到了您的字典方式,这对我很好,我正在研究nsdictionary如何与block一起工作,很高兴您有一些教程