在Objective-C中如何处理相关对象的NSArray

Ijo*_*chy 3 cocoa objective-c nsarray subclassing

Animal是一个BOOL名为属性的类alive.Monkey,Zebra并且Walrus是子类Animal.如果我有一个包含混合实例的NSArray调用zoo实例Monkey,Zebra并且Walrus,我想找到第一个活动Zebra实例,我可能会这样做:

Zebra *zebra; 
for (Animal *animal in zoo) {
    if ([animal isMemberOfClass:[Zebra class]] && animal.alive) {
        zebra = animal;
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是编译器在设置时抱怨不兼容的指针类型zebra = animal.如果我像那样做一些铸造zebra = (Zebra *)animal似乎工作,但我不确定在Objective-C中这种铸件是否安全.

处理这种情况的更好方法是什么?

Ext*_*ire 5

你遇到了"是个"问题.

如果您已分配zebraanimal,就不会有任何问题,因为类的zebra就是Zebra,这"是" Animal.

但是你正在做什么,你要分配animal给超类zebra,但是animal属于Animal类."是一个"测试失败,但一个简单的铸造:

zebra = (Zebra *)animal;
Run Code Online (Sandbox Code Playgroud)

负责编译器警告.是的,它是安全的.

这是一种更现代的做同样事情的方式.顺便说一句,由于在最后一行-objectAtIndex:返回id,因此不会出现上述问题:

NSUInteger index = [zoo indexOfObjectPassingTest:^BOOL(Animal *animal, NSUInteger idx, BOOL *stop) {
    return ([animal isMemberOfClass:[Zebra class]] && animal.alive);
}];
Zebra *zebra = (index != NSNotFound) ? [zoo objectAtIndex:index] : nil;
Run Code Online (Sandbox Code Playgroud)

请注意,我没有调整的参数从块一个id objAnimal *animal; 如果您知道您的集合仅包含对实例的引用Animal,那么您当然可以这样做.