You're experiencing an "is a" problem.
If you had been assigning zebra
to animal
, there would have been no issue, since the class of zebra
is Zebra
, which "is a" Animal
.
But with what you're doing, you're assigning animal
to zebra
, but animal
is of class Animal
, the superclass. The "is a" test fails, but a simple casting:
zebra = (Zebra *)animal;
takes care of the compiler warning. And yes, it's safe.
Here's a more modern way of doing the same thing. Incidentally, since, in the last line, -objectAtIndex:
returns id
, the aforementioned problem doesn't arise :
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;
Note that I did tweak one of the arguments to the block from id obj
to Animal *animal
; if you know your collection contains only references to instances of Animal
, you certainly can do this.