Para mayor claridad, me gusta hacer un bucle inicial donde recopilo los elementos para eliminar. Luego los elimino. Aquí hay una muestra usando la sintaxis de Objective-C 2.0:
NSMutableArray *discardedItems = [NSMutableArray array];
for (SomeObjectClass *item in originalArrayOfItems) {
if ([item shouldBeDiscarded])
[discardedItems addObject:item];
}
[originalArrayOfItems removeObjectsInArray:discardedItems];
Entonces no hay dudas sobre si los índices se están actualizando correctamente u otros pequeños detalles de contabilidad.
Editado para agregar:
Se ha observado en otras respuestas que la formulación inversa debería ser más rápida. es decir, si itera por la matriz y compone una nueva matriz de objetos para guardar, en lugar de objetos para descartar. Eso puede ser cierto (aunque ¿qué pasa con la memoria y el costo de procesamiento de asignar una nueva matriz y descartar la anterior?) Pero incluso si es más rápida, puede no ser tan importante como lo sería para una implementación ingenua, porque NSArrays no se comporten como matrices "normales". Hablan la charla pero caminan un camino diferente. Vea un buen análisis aquí:
La formulación inversa puede ser más rápida, pero nunca he tenido que preocuparme si es así, porque la formulación anterior siempre ha sido lo suficientemente rápida para mis necesidades.
Para mí, el mensaje final es usar cualquier formulación que sea más clara para usted. Optimice solo si es necesario. Personalmente, considero que la formulación anterior es más clara, por eso la uso. Pero si la formulación inversa es más clara para usted, hágalo.