Domanda

Voglio fare tutti gli oggetti in un array di eseguire un selettore. Ho scoperto il metodo makeObjectsPerformSelector: nome appropriato, ma ho una domanda con esso. Se lo uso su un array, cambierà la matrice esistente o restituire una nuova? Se si modifica l'oggetto esistente, quale sia il modo più semplice per restituire un nuovo array con il selettore applicata?

È stato utile?

Soluzione

makeObjectsPerformSelector: sta per eseguire tale selettore contro ogni oggetto dell'array. Se tali oggetti sono modificate dal selettore verranno modificate. Esso non restituisce nulla. Ora, v'è una cattura, che che di default la maggior parte delle copie a Cocoa sono copie poco profonde, il che significa che si ottiene un nuovo array, ma gli oggetti sottostanti cui punta sono gli stessi oggetti. Sarà necessario utilizzare initWithArray: copyItems per farlo copiare gli elementi di livello principale pure. 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)];

Altri suggerimenti

  

Se lo uso su un array, cambierà la matrice esistente o restituire una nuova?

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 ricezione, perché è impossibile.

C'è NSMutableArray, e dato che è una sottoclasse di NSArray, eredita makeObjectsPerformSelector:. Tuttavia, se NSMutableArray cambiato il comportamento di quel metodo, la sua documentazione dovrebbe avere una propria lista per il metodo (vedere le molte definizioni di init nella documentazione varie classi). Non esiste una lista, in modo da poter tranquillamente (e correttamente) dedurre che -[NSMutableArray makeObjectsPerformSelector:] funziona esattamente allo stesso modo di -[NSArray makeObjectsPerformSelector:].

Gli oggetti stessi possono modificare in risposta al vostro messaggio, ma la matrice stessa conterranno gli stessi oggetti dopo makeObjectsPerformSelector: come prima.

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

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

Questo sarà solo di lavoro se gli oggetti in grado di gestire un '-valueForKey: @ 'foo'' il messaggio e, ovviamente, è adatto solo per i metodi che prendono senza argomenti e restituiscono un valore non-zero.

Spero di interpretare correttamente questo ...

Se lo fai [myArray makeObjectsPerformSelector: someSelector], si sta efficacemente solo scorrendo myArray e l'invio del messaggio di selezione per ogni oggetto. La matrice è invariato perché makeObjectsPerformSelector non è consentito cambiare il contenuto.

Così, alla fine, hai la stessa matrice con gli stessi oggetti.

Nel seguente esempio, si può vedere è creato uno superView e 10 visualizzazione secondaria aggiunto ad esso, poi a ciascuno di loro di inviare removeFromSuperView (un metodo che è esiste in classe view) ed il risultato è zero visualizzazione secondaria in superView.

Se familiarità con JavaScript e cercare di trovare qualcosa di simile map in JavaScript, questo non è così. map eseguire una funzione su ogni elemento dell'array e sostituirlo con esito ma qui makeObjectsPerformSelector eseguire un metodo che esistono in ciascun oggetto dell'array.

UIView* superView = [[UIView alloc] initWithFrame:CGRectZero];

for(int i = 0; i < 10; i++){
    UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
    [superView addSubview:view];
}

NSLog(@"count = %lu", (unsigned long)[superView.subviews count]); // 10
[superView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; // removeFromSuperview is exist in `view`, you can call [view removeFromSuperview];
NSLog(@"count = %lu", (unsigned long)[superView.subviews count]); // 0
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top