2009-02-18 4 views
17

Voglio rendere tutti gli oggetti in una matrice eseguire un selettore. Ho scoperto il metodo appropriato denominato makeObjectsPerformSelector:, ma ho una domanda con esso. Se lo uso su un array, cambierà l'array esistente o ne restituirà uno nuovo? Se modifica l'oggetto esistente, qual è il modo più semplice per restituire un nuovo array con il selettore applicato?makeObjectsPerformSelector:

risposta

29

makeObjectsPerformSelector: eseguirà quel selettore su ogni oggetto dell'array. Se quegli oggetti sono modificati dal selettore saranno modificati. Non restituisce nulla. Ora, c'è un problema, che per impostazione predefinita la maggior parte delle copie in Cocoa sono copie poco profonde, il che significa che si ottiene un nuovo array, ma gli oggetti sottostanti a cui punta sono gli stessi oggetti. Sarà necessario utilizzare initWithArray: copyItems per fare in modo che copi anche gli elementi del livello root. Se si desidera un nuovo array contenente gli oggetti alterati così come la vecchia matrice fare qualcosa di simile:

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

Il selettore passato a '-makeObjectsPerformSelector:' non accetta argomenti.(È in [i documenti] (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html).) Tuttavia il tuo selettore, come mostrato, lo fa. – trudyscousin

2

Spero di interpretare correttamente questo ...

Se lo fai [makeObjectsPerformSelector myArray: someSelector], stai semplicemente iterando attraverso myArray e inviando il messaggio di selezione a ciascun oggetto. La matrice è invariata poiché makeObjectsPerformSelector non può modificare il suo contenuto.

Quindi, alla fine, hai lo stesso array con gli stessi oggetti.

+2

Sì. makeObjectsPerformSelector: è praticamente una scorciatoia per scrivere questo: per (oggetto id nell'array) { [object someSelector: someArgument]; } – Alex

15

Se lo utilizzo su un array, cambierà l'array esistente o ne restituirà uno nuovo?

No.

Prima di tutto, leggere la firma:

- (void)makeObjectsPerformSelector:(SEL)aSelector 

void, senza stelle dopo di esso, significa “non restituisce nulla”.

In secondo luogo, si noti che questo è un metodo di NSArray, che è una classe immutabile. Pertanto, makeObjectsPerformSelector: non muta la matrice di ricezione, perché è impossibile.

C'è NSMutableArray e poiché è una sottoclasse di NSArray, eredita lo makeObjectsPerformSelector:. Tuttavia, se NSMutableArray ha cambiato il comportamento di quel metodo, la sua documentazione avrebbe il proprio elenco per il metodo (vedere le numerose definizioni di init nella documentazione di varie classi). Non esiste un elenco di questo tipo, quindi è possibile dedurre in modo sicuro (e correttamente) che lo -[NSMutableArray makeObjectsPerformSelector:] funziona esattamente allo stesso modo di -[NSArray makeObjectsPerformSelector:].

Gli oggetti possono essere modificati in risposta al messaggio, ma l'array stesso conterrà gli stessi oggetti dopo lo makeObjectsPerformSelector: come prima.

+0

Sì. Vengo all'obiettivo-c dal rubino, quindi a volte mi dimentico della digitazione dell'oggetto. Ho capito cosa fa veramente makebjectsPerformSelector dopo averci pensato per un po '. – Allyn

7

A seguito di altre risposte, se si fai vogliono creare un nuovo array con il risultato della chiamata di un metodo, si può fare questo:

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

Ciò solo lavoro se gli oggetti in grado di gestire un messaggio '-valueForKey: @ "foo"' e, ovviamente, è adatto solo per metodi che non accettano argomenti e restituiscono un valore non nullo.