2010-12-29 20 views
5

Come si chiama un metodo @selector con più argomenti?@selector con più argomenti

Ho il seguente

[self performSelector:@selector(changeImage:withString:) withObject:A1 withObject:fileString2 afterDelay:0.1]; 

ma ottengo un

selettore non riconosciuto inviato ad esempio

errore

Il mio metodo che io chiamo è la seguente

-(void) changeImage: (UIButton *) button withString: (NSString *) string 
{ 
[button setImage:[UIImage imageNamed:string] forState:UIControlStateNormal]; 
} 

risposta

18

Si dovrebbe usare NSInvocation

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: 
          [self methodSignatureForSelector:@selector(changeImage:withString:)]]; 
[invocation setTarget:self]; 
[invocation setSelector:@selector(changeImage:withString:)]; 
[invocation setArgument:A1 atIndex:2]; 
[invocation setArgument:fileString2 atIndex:3]; 
[NSTimer scheduledTimerWithTimeInterval:0.1f invocation:invocation repeats:NO]; 
+0

Cool, grazie. Come lo chiamo. Voglio chiamarlo in molti posti. Quindi può essere dichiarato nel metodo viewDidLoad e quindi essere chiamato in vari luoghi? – jarryd

+0

Non capisco davvero cosa intendi. Puoi mettere questo pezzo di codice ovunque nella classe in cui changeImage: withString: è definito. Se si desidera chiamarlo più volte, è necessario includerlo in un metodo e chiamare invece tale metodo. – Jilouc

+1

alternativamente, si può fare '[invocation performSelector: @selector (invoke) withObject: nil afterDelay: 0.1];' – user102008

0

Stai chiamando performSelector:withObject:withObject:afterDelay:, ma questo metodo non esiste.

L'unica opzione è performSelector:withObject:withObject:, ma non è possibile specificare un ritardo con tale metodo. Se hai bisogno di un ritardo, probabilmente dovresti creare una categoria per NSObject e creare un nuovo metodo tu stesso.

4

classe Il NSObject ha un metodo performSelector:withObject:afterDelay:, e il protocollo NSObject specifica un metodo performSelector:withObject:withObject:, ma da nessuna parte c'è specificato un performSelector:withObject:withObject:afterDelay:.

In questo caso, sarà necessario utilizzare uno NSInvocation per ottenere la funzionalità desiderata. Configura l'invocazione, quindi puoi chiamare lo performSelector:withObject:afterDelay sull'invocazione stessa, utilizzando il selettore invoke e un oggetto nil.

1

Non è un buon modo per ottenere intorno ad esso, ma se si voleva si poteva modificare il metodo di accettare un NSArray, quando l'oggetto nella posizione di indice 0 è il pulsante e al l'indice 1 è la stringa.

3

Non esiste un metodo per eseguire un selettore con più argomenti e un ritardo. Si potrebbe avvolgere il pulsante e l'oggetto stringa in un NSDictionary per ovviare a questo in questo modo:

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:A1,@"button",fileString2,@"string",nil]; 
[self performSelector:@selector(changeWithDict:) withObject:dict afterDelay:0.1]; 
//... 

-(void)changeWithDict:(NSDictionary *)dict { 
    [[dict objectForKey:@"button"] setImage:[UIImage imageNamed:[dict objectForKey:@"string"]] forState:UIControlStateNormal]; 
} 
2

Se ci si rivolge iOS 4.0+ è possibile utilizzare i blocchi. Qualcosa in questo senso dovrebbe fare il trucco.

// Delay execution of my block for 0.1 seconds. 
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC/10ull), dispatch_get_current_queue(), ^{ 
    [self changeImage:A1 withString:fileString2]; 
}); 
+0

Lo terrò a mente, ma sto prendendo di mira da 3.0. – jarryd

+0

In tal caso è necessario utilizzare il metodo NSInvocation fornito da altri. I blocchi sono stati introdotti solo in iOS 4.0. – extremeboredom