3

可能重复:
为什么当我指定 NSStrings 时快速枚举不跳过 NSNumbers?

我最近在使用快速枚举时注意到了一些意外行为。事后看来,我可能期望快速枚举能做的比预期的要多,所以我正在寻找一些关于它实际上是如何工作的澄清。

假设我有一个父类Shape,它有 2 个子类3SidedShape4SidedShape。我有一个名为myShapes的数组,其中包含来自 3 面和 4 面类的对象。

如果我想搜索数组myShapes,但我只关心 3 个边的形状,我正在做的是:

 for (3SidedShape *shape in myShapes)

我的想法是我只会迭代3SidedShape类的对象,但事实并非如此?我想无论他们喜欢与否,我都将所有对象都转换为3SidedShape 。我晚上将对象作为完全不同的课程归还。诚然,我没有调用两个类都没有的任何方法,但我没想到类兄弟姐妹会如此轻松地重新转换?我只是在这里走运,还是你真的可以列举任何你喜欢的班级,不管关系如何?谁能解释枚举期间实际发生的情况?

4

1 回答 1

3

for...in循环中指定的类型,也就是快速枚举,将集合中的所有元素转换为指定的类型。它们“如此容易地重新铸造”的原因是铸造不会将一种类型的对象变成另一种类型的对象(这将如何工作?)。这是对编译器的一个提示,告诉它将该对象视为另一种类型,就好像在说“别担心,这个对象属于(insert type),所以类型检查它是这样的。” 向对象发送它无法处理的消息,但它被转换为可以处理的类型,仍然会使应用程序崩溃。你应该做的是:

for (id shape in myShapes){
    if ([shape isKindOfClass: [3SidedShape class]]){
        //insert code here
    }
}

该代码不假定任何类型,使用自省仅对3SidedShape类型或 3SidedShape 的子类的对象执行代码。对于精确检查(不包括子类),请使用isMemberOfClass:。小心使用isMemberOfClass:来测试类簇 (NSNumber) 中的类的成员资格,但是,因为它们的内部实现更复杂。

于 2012-09-11T01:55:08.947 回答