【问题标题】:Too much boiler plate code switch statement - iOS太多样板代码切换语句 - iOS
【发布时间】:2014-05-18 14:48:49
【问题描述】:

我有一个 switch 语句,它将适当地向 11 个 UILabel 添加文本。但是,它现在变得有点长,并且相同代码的副本太多了。我该如何进一步改进它?我可以制作一个标签数组,然后通过 for 循环访问它们吗?

这里是代码切换语句:

switch ([number_sorted count]) {

            case 1:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                break;

            case 2:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                break;

            case 3:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                break;

            case 4:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                break;

            case 5:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                break;

            case 6:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
                break;

            case 7:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
                label_7.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[6] integerValue]];
                break;

            case 8:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
                label_7.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[6] integerValue]];
                label_8.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[7] integerValue]];
                break;

            case 9:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
                label_7.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[6] integerValue]];
                label_8.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[7] integerValue]];
                label_9.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[8] integerValue]];
                break;

            case 10:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
                label_7.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[6] integerValue]];
                label_8.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[7] integerValue]];
                label_9.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[8] integerValue]];
                label_10.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[9] integerValue]];
                break;

            case 11:
                label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
                label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
                label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
                label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
                label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
                label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
                label_7.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[6] integerValue]];
                label_8.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[7] integerValue]];
                label_9.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[8] integerValue]];
                label_10.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[9] integerValue]];
                label_11.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[10] integerValue]];
                break;

            default:
                break;
        }

感谢您抽出宝贵时间,丹。

【问题讨论】:

  • 标签不是使用 11 个 ivars,而是使用标签数组。然后代码可以是一个单独的小循环。
  • 另一种解决方案是使用 objc_... 运行时函数动态查找标签,例如为标签创建选择器名称,然后调用 objc_msgSend()。无需那样更改他们的声明。

标签: ios cocoa-touch switch-statement uilabel boilerplate


【解决方案1】:

另一种选择是使用 switch 语句的“失败”属性

switch ([number_sorted count]) {
    case 11:
        label_11.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[10] integerValue]];
    case 10:
        label_10.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[9] integerValue]];
    case 9:
        label_9.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[8] integerValue]];
    case 8:
        label_8.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[7] integerValue]];
    case 7:
        label_7.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[6] integerValue]];
    case 6:
        label_6.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[5] integerValue]];
    case 5:
        label_5.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[4] integerValue]];
    case 4:
        label_4.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[3] integerValue]];
    case 3:
        label_3.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[2] integerValue]];
    case 2:
        label_2.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[1] integerValue]];
    case 1:
        label_1.text = [NSString stringWithFormat:@"%ld", (long)[number_sorted[0] integerValue]];
    default:
        break;
}

【讨论】:

  • 我喜欢这个解决方案。很聪明。
  • 不要小看@Rob的概念,它的适用性很一般
  • Rob 解决方案看起来不错,但它基于 IB 标签...我认为 Daij-Djan 解决方案是最好的,但我还不能让它工作。
  • 这个答案中的代码是安全的。通常,当break 丢失时,这是一个错误,但在这种情况下,这正是您真正想要的。作为惯例,我总是添加一条评论来代替缺少的break 澄清确实不应该存在。
  • 我还要补充一点,虽然这个答案很巧妙,但它仍然是错误的解决方案。由于简单的拼写错误,它很脆弱并且容易出现错误。它也不能很好地扩展。你真的应该使用“循环”解决方案。它的错误少得多,可扩展性更高,而且更容易读写。
【解决方案2】:

只需将您的 UILabel 放在 NSArray 中即可。然后你可以遍历数组。在Interface Builder中,您可以将一堆元素添加到IBOutletCollection,这很方便(只需将多个东西拖到一起,例如创建IBOutlet,它会提供IBOutletCollection)。

请注意,IBOutletCollection 不对订单做出任何承诺。因此,您可能需要在 IB 中添加 tag 以跟踪它们。我经常在viewDidLoad 中按tag 对我的收藏进行排序。

如果您以编程方式构建此系统,则只需将它们放入数组即可开始。

有时跟踪tag 还是太痛苦了,所以我作弊了一点。我只是使用subviews 浏览所有视图并找到我的标签。然后我按 y-origin 对它们进行排序并将它们放在一个数组中。这当然有点脆弱,需要很多关于视图的特殊知识,但是视图控制器应该具备这些知识。我偶尔会使用这种技术来创建一个混合 IB/编程接口,这让我可以在 IB 中布置所有内容,然后在代码中连接所有内容(操作、字体选择等)。当有很多几乎相同的 UI 元素时,我尤其会这样做。

【讨论】:

    【解决方案3】:

    使用两个数组:1. 用于所有标签,2. 用于计数。
    你已经有了 2. 部分:

    首先,在您的班级中有一个NSArray *_labels
    然后在你的 viewDidLoad 中做_labels = @[label1, label2, label3];

    然后为开关

    for(int i = 0; i < number_sorted.count; i++) {
        ((UILabel*)_labels[i]).text = [NSString stringWithFormat:@"%ld", [number_sorted[i] integerValue]];
    }
    

    【讨论】:

    • 我收到错误,在“id”类型的对象上找不到属性“text”。
    • @Daij-Djan 我在 SO 中看到大量带有下划线“_”的变量和 ivars。我知道属性会生成带有前导下划线的 ivars,但为什么要以这种方式访问​​它们呢?通常,如果有一个属性,则应该通过 getter/setter 访问该值,例如 self.labels。对使用属性有一些偏见吗?有没有推荐这个的讲师/课程或教程?
    • 哦,我的坏@Supertecnoboff 不要使用 .语法或强制转换。我“修复”了代码
    • @zaph 是的。不过,我从来没有说过要创建财产 :) 不会将财产用于私人物品。
    • @Daij-Djan 只是想知道为什么不这样做,有什么指示不要这样做吗?我最近在 SO 上看到了很多这样的例子。
    猜你喜欢
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    相关资源
    最近更新 更多