2011-11-13 19 views

Respuesta

62

Mira la API para NSArray y verá el método

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block 

Así dan que un un intento

[savedArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 

    //... Do your usual stuff here 

    obj // This is the current object 
    idx // This is the index of the current object 
    stop // Set this to true if you want to stop 

}]; 
+10

para agregar - la bandera de parada se usa para llamar a '* stop = YES' (simplemente' stop = YES' no funciona) – Tim

+2

me pregunto si esto es más rápido, simplemente agregando un número entero de índice –

9

supongo que la solución más contundente para esto sería simplemente incrementar un índice manualmente.

NSUInteger indexInSavedArray = 0; 
for (MyClass *entry in savedArray) { 
    indexInSavedArray++; 
} 

Como alternativa, simplemente no puede usar la enumeración rápida.

for (NSUInteger indexInSavedArray = 0; indexInSavedArray < savedArray.count; indexInSavedArray++) { 
     [savedArray objectAtIndex:indexInSavedArray]; 
    } 
+5

También se puede usar '[savedArray indexOfObject: la entrada];' :) –

+6

Sí, eso funcionaría, aunque sería muy ineficiente, ya que tendría que enviar IsEqual a cada objeto que conduce al objeto coincidente . Por ejemplo, se necesitarían 500 envíos de mensajes isEqual (y cálculos si el objeto realmente hace algo en real en isEqual) para obtener el índice del elemento 500 y luego 501 mensajes más para obtener el siguiente objeto después de eso. editar: tal vez estabas siendo sarcástico y perdí una broma :) –

7

Esta pregunta ya ha sido contestada, pero pensé que agregaría que las iteraciones de recuento es en realidad la técnica mencionada en la documentación de la biblioteca del desarrollador de iOS:

NSArray *array = <#Get an array#>; 
NSUInteger index = 0; 

for (id element in array) { 
    NSLog(@"Element at index %u is: %@", index, element); 
    index++; 
} 

Estaba seguro de que habría un truco elegante, pero supongo que no. :)

+1

El camino de Apple es inseguro y en mi humilde opinión debe ser evitado: va horriblemente mal cuando alguien agrega inocentemente un "descanso" o un "continuar" a su código. Tristemente, su diseño para Fast Enumeration simplemente no era muy bueno. – Adam

+0

¿Quiere decir que algo va mal si se coloca el "corte" o "continuar" dentro del código de Enumeración rápida? ¿Apple hizo algo diferente de, digamos, C#? Solo solicitando mi propia educación (y evitando errores futuros). ¡Gracias! – GrandAdmiral

+3

Ejemplo simple: el código de ejemplo tiene 2 líneas de longitud. ¿Qué pasa si tiene 20 líneas y en la línea 5 alguien agrega "continuar"? El continuar hará que el "elemento" avance, pero no el "índice". Aha! Entonces colocas el índice ++ al comienzo, justo después del punto donde se usó. Pero, ¿qué pasa si alguien intenta hacer referencia más adelante en el cuerpo del bucle? Ahora es demasiado grande para 1. ... etc – Adam

0

Una simple observación: si inicializa el índice en -1 y luego pone el índice ++ como la primera línea en el ciclo for, eso no cubre todas las bases (siempre que alguien no deslice el código en frente al incremento)?

+1

"siempre que alguien no deslice el código en frente del incremento" Codificación basada en la fe en su máxima expresión – Tim

3

Si desea acceder al índice o devolver el bloque externo, aquí hay un fragmento de código que puede ser útil. (considerando que la matriz es una matriz de NSString).

- (NSInteger) findElemenent:(NSString *)key inArray:(NSArray *)array 
{ 
    __block NSInteger index = -1; 
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     if ([obj isEqualToString:key]) { 
      *stop = YES; 
      index = idx; 
     } 
    }]; 
    return index; 
} 
Cuestiones relacionadas