Embora essa pergunta seja antiga, as coisas não mudaram, a resposta aceita está incorreta.
A enumerateObjectsUsingBlock
API não foi substituída for-in
, mas para um caso de uso totalmente diferente:
- Permite a aplicação de lógica arbitrária e não local. ou seja, você não precisa saber o que o bloco faz para usá-lo em uma matriz.
- Enumeração simultânea para coleções grandes ou computação pesada (usando o
withOptions:
parâmetro)
A Enumeração Rápida com for-in
ainda é o método idiomático de enumerar uma coleção.
A Enumeração Rápida se beneficia da brevidade do código, da legibilidade e das otimizações adicionais, que a tornam estranhamente rápida. Mais rápido que um loop for C antigo!
Um teste rápido conclui que no ano de 2014 no iOS 7, enumerateObjectsUsingBlock
é consistentemente 700% mais lento que o for-in (com base nas iterações de 1 mm de uma matriz de 100 itens).
O desempenho é uma preocupação prática real aqui?
Definitivamente não, com raras exceções.
O objetivo é demonstrar que há pouco benefício em usar enumerateObjectsUsingBlock:
mais defor-in
sem uma boa razão. Não torna o código mais legível ... ou mais rápido ... ou seguro para threads. (outro equívoco comum).
A escolha se resume à preferência pessoal. Para mim, a opção idiomática e legível vence. Nesse caso, isso é enumeração rápida usando for-in
.
Referência:
NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
arr[i] = [NSString stringWithFormat:@"%d", i];
}
int i;
__block NSUInteger length;
i = 1000 * 1000;
uint64_t a1 = mach_absolute_time();
while (--i > 0) {
for (NSString *s in arr) {
length = s.length;
}
}
NSLog(@"For-in %llu", mach_absolute_time()-a1);
i = 1000 * 1000;
uint64_t b1 = mach_absolute_time();
while (--i > 0) {
[arr enumerateObjectsUsingBlock:^(NSString *s, NSUInteger idx, BOOL *stop) {
length = s.length;
}];
}
NSLog(@"Enum %llu", mach_absolute_time()-b1);
Resultados:
2014-06-11 14:37:47.717 Test[57483:60b] For-in 1087754062
2014-06-11 14:37:55.492 Test[57483:60b] Enum 7775447746