2009-02-18 4 views
17

Quiero hacer que todos los objetos de una matriz realicen un selector. Descubrí el método makeObjectsPerformSelector: apropiadamente llamado, pero tengo una pregunta con él. Si lo uso en una matriz, ¿cambiará la matriz existente o devolverá una nueva? Si modifica el objeto existente, ¿cuál es la forma más fácil de devolver una nueva matriz con el selector aplicado?makeObjectsPerformSelector:

Respuesta

29

makeObjectsPerformSelector: va a ejecutar ese selector contra cada objeto en la matriz. Si esos objetos son modificados por el selector, serán modificados. No devuelve nada Ahora, hay una trampa, que por defecto la mayoría de las copias en Cocoa son copias poco profundas, lo que significa que obtienes una nueva matriz, pero los objetos subyacentes a los que apunta son los mismos objetos. Tendrá que usar initWithArray: copyItems para que también copie los elementos del nivel raíz. Si desea una nueva matriz que contiene los objetos alterados, así como la matriz de edad hacer algo como esto:

NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES]; 
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)]; 
+4

El selector pasado a '-makeObjectsPerformSelector:' no toma argumentos.(Está en [los documentos] (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html). Sin embargo, su selector, como se muestra, sí lo hace. – trudyscousin

2

espero que estoy interpretando esto correctamente ...

Si lo hace makeObjectsPerformSelector miMatriz [: someSelector], en realidad está simplemente iterando a través de myArray y enviando el mensaje selector a cada objeto. La matriz no se modifica porque makeObjectsPerformSelector no puede cambiar su contenido.

Así que al final, tienes la misma matriz con los mismos objetos.

+2

Sí. makeObjectsPerformSelector: es básicamente un atajo para escribir esto: para (objeto id en array) { [object someSelector: someArgument]; } – Alex

15

Si lo uso en una matriz, ¿cambiará la matriz existente o devolverá una nueva?

En primer lugar, leer la firma:

- (void)makeObjectsPerformSelector:(SEL)aSelector 

void, sin estrellas después de ella, significa “no devuelve nada”.

En segundo lugar, tenga en cuenta que este es un método de NSArray, que es una clase inmutable. Por lo tanto, makeObjectsPerformSelector: no muta la matriz de recepción, porque eso es imposible.

No es NSMutableArray, y ya que es una subclase de NSArray, hereda makeObjectsPerformSelector:. Sin embargo, si NSMutableArray cambia el comportamiento de ese método, su documentación tendría su propia lista para el método (consulte las diversas definiciones de init en la documentación de varias clases). No existe tal listado, por lo que puede inferir (y correctamente) que -[NSMutableArray makeObjectsPerformSelector:] funciona exactamente de la misma manera que -[NSArray makeObjectsPerformSelector:].

Los objetos pueden modificarse a sí mismos en respuesta a su mensaje, pero la matriz contendrá los mismos objetos después de makeObjectsPerformSelector: que antes.

+0

Sí. Estoy llegando a Objective-c desde ruby, por lo que a veces me olvido de la tipificación de objetos. Me di cuenta de lo que makeObjectsPerformSelector realmente hace después de pensarlo por un tiempo. – Allyn

7

Además de otras respuestas, si hace quieren crear una nueva matriz con el resultado de llamar a un método, se puede hacer esto:

NSArray *derivedArray = [originalArray valueForKey:@"foo"]; 

Esto única trabajo si sus objetos puede manejar un mensaje '-valueForKey: @ "foo"' y, obviamente, solo es adecuado para métodos que no toman argumentos y devuelven un valor no nulo.