7

在 Obj-C 中,开关只能评估数字。我希望能够使用它来比较对象的类,例如:

switch (currentSubViewController.class) 
{
     case UITableViewController.class :
          <do stuff>
          break;
     case UICollectionViewController.class :
          <do stuff>
          break;
}

有什么办法可以做到这一点?我真的很想能够使用开关,因为它可以很容易地阅读不同的案例,而且我可以在将来的任何时候添加更多案例。有任何想法吗?

4

5 回答 5

9

如本论坛帖子中所述,您最好应用Liskov 替换原则并将<do stuff>逻辑放入实际类中,然后调用由所有这些类继承的超类共享的方法(或者如果您是 Obj-C 中的协议计划让这个逻辑在完全不同的类之间共享)。

这封装了每个实现/子类中的所有逻辑,而更高级别的类不需要担心您可能拥有的每一个可能的实现。这提高了可维护性,并且在面向对象编程中更常见,而不是普通的旧过程编程。

于 2013-05-19T23:29:14.867 回答
1

switch语句仅适用于整数类型。你需要一个大块if-else

如果你真的想强制执行一个switch语句,那么你可以使用一个固定的类数组来计算出一些东西,然后关闭你正在检查的类的索引位置。但是为了 case 语句的可读性,您需要定义一组表示每个类的索引位置的常量。if-else为了避免和阻止,需要维护大量的工作和代码。

于 2013-05-19T23:30:42.300 回答
0

那是不可能的。你必须使用if-elseif这样的声明

if ([currentSubViewController isMembefOrClass:[UITableViewController class]]) 
{
    <do stuff>
} else if ([currentSubViewController isMemberOfClass:[UICollectionViewController class]]) {

}

请注意,我isMemberOfClass:用来模拟switch-case语句会做什么。但在大多数情况下你想使用isKindOfClass:

于 2013-05-19T23:30:35.373 回答
0

您可以使用字典文字。

((void(^)())@{
NSStringFromClass([UITableViewController class]) : [^{
    // stuff
} copy],
NSStringFromClass([UICollectionViewController class]) : [^{
    // stuff
} copy]
}[NSStringFromClass([currentSubViewController class])])();

注意:这只是为了好玩。请不要把它当作一个严肃的建议。

认真使用@AramKocharyan 的答案。

于 2013-05-19T23:50:20.663 回答
0

一种方法是构建一个数据结构,将您关心的类映射到enum. 这将是很多样板代码。

不幸的是,Objective-C 没有switch像 Ruby 这样的面向对象的条件语言。它只有 Cswitch语句。caseC 语句中的Aswitch需要一个整数常量,这就是阻止使用 Cswitch语句的更动态方法的原因。C 枚举类型也适用于常量。这意味着两者都不能在运行时生成,但可以在编译时生成。

C 枚举和 switch 语句可以很好地协同工作,但对于对象来说并不那么热门。

因此,您最好在if-else此处使用复合语句进行比较。

于 2013-05-20T01:24:16.580 回答