快速枚举不能在objective-c中给出正确的对象类型?

zyl*_*024 1 iphone objective-c ios

我觉得这很奇怪.所以我有一个UIView,我想改变textcolor所有UILabel.这是我做的:

for (UILabel *label in [self subviews]) { // self is the UIView
    label.textColor = someColor;
}
Run Code Online (Sandbox Code Playgroud)

当我运行代码时,它崩溃了,就像错误一样 UIImageView: unrecognized selector setTextColor: sent to instance (some instance)

所以看起来label在快速枚举中实际上是一个UIImageView.顺便说一句,我有两个UIImageView在S UIView *self.但是,快速枚举不应该UILabel只给出(因为我指定UILabel *label而不是UIView *label)?

我认为这是问题,因为当我编写以下代码时,它可以工作.

for (UILabel *label in [self subviews]) { // self is the UIView
    if ([label isKindOfClass:[UILabel class]]) {
        label.textColor = someColor;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在这段代码中,当我检查以确保它label是a UILabel然后设置它时textcolor,UILabel视图中的所有s都会正确地改变它们的颜色.

有人可以解释为什么我需要if-statement仔细检查实例类型吗?

Wai*_*ain 5

你的2个循环非常不同.第一个假设所有子视图都是标签,第二个检查每个子视图以确保它是标签.第一个应该检查.

快速枚举基本上是语法糖,它只是一个正常的for循环.它不会神奇地过滤或操纵您枚举的列表.


Ben*_*tto 5

你正在阅读枚举作为"我的子视图中每个UILabel的循环",但这不是它真正起作用的方式 - 快速枚举不做任何智能过滤​​,它只是一个捷径.您应该将其读作"我的子视图中的每个对象的循环,这些是UILabels".并且因为不是每个子视图实际上都是UILabel,所以在尝试将它们全部视为一个时会遇到问题.

该阵列中的每个对象都是一个UIView虽然,这样更能说明问题的语法是:

for (UIView * view in self.subviews) {
    if ([view isKindOfClass:[UILabel class]]) {
        UILabel * label = (UILabel *)view;
        // do something with label...
    }
}
Run Code Online (Sandbox Code Playgroud)