Obwohl diese Frage alt ist, haben sich die Dinge nicht geändert, die die akzeptierte Antwort ist falsch.
Die enumerateObjectsUsingBlock
API sollte nicht ersetzen for-in
, sondern für einen völlig anderen Anwendungsfall:
- Es ermöglicht die Anwendung beliebiger, nicht lokaler Logik. Das heißt, Sie müssen nicht wissen, was der Block tut, um ihn in einem Array zu verwenden.
- Gleichzeitige Aufzählung für große Sammlungen oder umfangreiche Berechnungen (unter Verwendung des
withOptions:
Parameters)
Schnelle Aufzählung mit for-in
ist immer noch die idiomatische Methode zum Auflisten einer Sammlung.
Die schnelle Aufzählung profitiert von der Kürze des Codes, der Lesbarkeit und zusätzlichen Optimierungen , die ihn unnatürlich schnell machen. Schneller als eine alte C-for-Schleife!
Ein schneller Test kommt zu dem Schluss, dass das Jahr 2014 unter iOS 7 enumerateObjectsUsingBlock
durchweg 700% langsamer ist als das For-In (basierend auf 1-mm-Iterationen eines 100-Elemente-Arrays).
Ist Leistung hier ein echtes praktisches Anliegen?
Auf keinen Fall, mit seltenen Ausnahmen.
Der Punkt ist zu zeigen, dass die Verwendung von enumerateObjectsUsingBlock:
Over for-in
ohne wirklich guten Grund wenig Nutzen bringt. Es macht den Code nicht lesbarer ... oder schneller ... oder threadsicherer. (ein weiteres häufiges Missverständnis).
Die Wahl hängt von den persönlichen Vorlieben ab. Für mich gewinnt die idiomatische und lesbare Option. In diesem Fall ist dies die schnelle Aufzählung mit for-in
.
Benchmark:
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);
Ergebnisse:
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