在快速枚举期间实际发生了什么?

时间:2012-09-11 01:04:14

标签: iphone objective-c arrays casting enumeration

  

可能重复:
  Why does fast enumeration not skip the NSNumbers when I specify NSStrings?

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

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

如果我想搜索数组 myShapes ,但我只关注三面形状我正在做的是:

 for (3SidedShape *shape in myShapes)

我的想法是我只会迭代类 3SidedShape 的对象,但事实并非如此?我想我将所有对象都投射为 3SidedShape ,无论他们喜欢与否。我晚上作为一个完全不同的课程返回对象。当然,我并没有打电话给两个班级都没有的任何方法,但是我没想到班级兄弟会如此轻易地重新演绎?我是不是在这里幸运,或者你真的可以列举任何你喜欢的课程,无论关系如何?任何人都可以解释枚举过程中实际发生的事情吗?

1 个答案:

答案 0 :(得分:3)

for ... in 循环中指定的类型,也就是快速枚举,将集合中的所有元素强制转换为指定的类型。他们“如此轻易地重新投射”的原因是,施法不会将一种类型的物体变成另一种物体(这将如何起作用?)。这是一个提示编译器告诉它将对象视为另一种类型的暗示,好像说“别担心,这个对象是(插入类型),所以键入检查它因此。”向对象发送一个无法处理的消息,但它所输入的类型仍然可以使应用程序崩溃。你应该做的是:

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

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