2011-05-14 18 views
5

Digamos que tengo tres matrices del mismo tamaño. Tengo que hacer algo con todos los objetos. Si me gustaría utilizar una matriz estándar de C, que iba a escribir algo así comoEnumeración de NSArray múltiple

for (i = 0; i < size; i++) { 
    doSomething(array1[i]); // or [[array1 objectAtIndex:i] doSomething]; 
    doSomethingElse(array2[i]); // or [[array2 objectAtIndex:i] doSomethingElse]; 
    doSomethingReallySpecial(array3[i]); // or [[array3 objectAtIndex:i] doSomethingReallySpecial]; 
} 

Con el objetivo C llegamos más formas para desplazarse por los objetos en NSArray: enumeración rápida, enumeración basada en el bloque y utilizando los empadronadores. ¿Cuál debería usar y por qué? ¿Cual es la diferencia?

Editar
En realidad esta pregunta puede formularse así: si uno tiene que utilizar el índice de un elemento de una matriz, que la enumeración se debe utilizar?

Respuesta

0

Debe utilizar la que más claramente expresa la intención de su código para los lectores del código. A menos que haya identificado estos bucles como un cuello de botella de rendimiento significativo, la capacidad de mantener su código es mucho más importante.

Dicho esto, la enumeración rápida sola (es decir, for(id i in array)) no proporciona el índice. Si no desea utilizar un bucle de estilo C, -[NSArray enumerateObjectsUsingBlock:] proporciona tanto el elemento actual como el índice y podría utilizarse para comprimir varias matrices. Sospecho que, para las matrices múltiples, el enfoque del estilo C a menudo será efectivamente equivalente en el rendimiento, y tal vez más claro para el lector, pero debe tener un perfil para estar seguro.

Lo que estás buscando es una expresión común en la programación funcional y ciertamente podría implementarse sobre GCD usando bloques, pero no conozco ninguna implementación.

4

Los métodos basados ​​en NSEnumerator alguna vez fueron la única forma admitida para enumerar. No puedo pensar en ninguna ventaja que tenga sobre los demás: es más lenta y más difícil de manejar y ha sido sustituida en gran medida por los otros métodos.

El uso de bloques permite una gran flexibilidad. Un método podría aceptar un bloque como argumento y usar eso para enumerar lo largo de varias colecciones diferentes:

- (void) doSomethingToFruits:(void(^)(id,NSUInteger,BOOL*))block 
{ 
    [apples enumerateObjectsUsingBlock:block]; 
    [bananas enumerateObjectsUsingBlock:block]; 
    [kiwis enumerateObjectsUsingBlock:block]; 
} 

También puede utilizar el argumento opciones en enumerateObjectsUsingBlock:options: enumerar más de contenidos al mismo tiempo ,.

Algo que me gusta de la enumeración rápida es que el protocolo NSFastEnumeration me permite añadir un método que acepta cualquiera de las matrices o en grupos, (o tablas hash o lo que sea), pero aún tiene tipo estático comprobar en el argumento:

- (void) addObjectsFromCollection:(id<NSFastEnumeration>)coll 
{ 
    for (id obj in coll) [self addObject:obj]; 
} 

De lo contrario, la sintaxis de los dos parece encajar mejor en diferentes contextos. Me parece que si el cuerpo principal de un método se enumera en una colección, está más claro lo que está sucediendo si uso la enumeración rápida, mientras que si solo quiero realizar una o dos acciones en todos los contenidos en medio de un método más grande, bloquea son más concisos, pero creo que esta parte se debe a las preferencias personales.

Adición:

Si desea realizar un seguimiento del índice, la opción de bloque acepta un índice como argumento.

+0

gracias por una respuesta completa! – adubr

Cuestiones relacionadas