Para maior clareza, gosto de fazer um loop inicial onde coleciono os itens a serem excluídos. Então eu os apago. Aqui está um exemplo usando a sintaxe do Objective-C 2.0:
NSMutableArray *discardedItems = [NSMutableArray array];
for (SomeObjectClass *item in originalArrayOfItems) {
if ([item shouldBeDiscarded])
[discardedItems addObject:item];
}
[originalArrayOfItems removeObjectsInArray:discardedItems];
Não há dúvidas sobre se os índices estão sendo atualizados corretamente ou outros pequenos detalhes da contabilidade.
Editado para adicionar:
Observou-se em outras respostas que a formulação inversa deve ser mais rápida. ou seja, se você percorrer a matriz e compor uma nova matriz de objetos a serem mantidos, em vez de objetos a serem descartados. Isso pode ser verdade (embora o que dizer da memória e do custo de processamento de alocar uma nova matriz e descartar a antiga?), Mas mesmo que seja mais rápido, pode não ser tão importante quanto seria para uma implementação ingênua, porque o NSArrays não se comporte como matrizes "normais". Eles falam a conversa, mas andam uma caminhada diferente. Veja uma boa análise aqui:
A formulação inversa pode ser mais rápida, mas nunca precisei me importar se é, porque a formulação acima sempre foi rápida o suficiente para minhas necessidades.
Para mim, a mensagem para levar para casa é usar qualquer formulação que seja mais clara para você. Otimize apenas se necessário. Pessoalmente, acho a formulação acima mais clara, e é por isso que a uso. Mas se a formulação inversa for mais clara para você, faça isso.