2010-12-29 16 views
5

Jak wywołać metodę @selector z wieloma argumentami?@selector z wieloma argumentami

Mam następujący

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

ale dostać

nierozpoznany selektor wysyłane do instancji

błąd

Moja metoda Wołam jest następujący

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

Odpowiedz

18

Należy użyć 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

Fajnie, dzięki. Jak to nazwać. Chcę to nazwać w wielu miejscach. Czy można go zadeklarować w metodzie viewDidLoad, a następnie wywołać w różnych miejscach? – jarryd

+0

Nie bardzo rozumiem, co masz na myśli. Możesz umieścić ten fragment kodu w dowolnym miejscu w klasie, gdzie zdefiniowano changeImage: withString:. Jeśli chcesz wywołać ją wiele razy, powinieneś zawinąć ją w metodę i wywołać tę metodę. – Jilouc

+1

naprzemiennie, możesz zrobić: "[invocation performSelector: @selector (invoke) withObject: nil afterDelay: 0.1];' – user102008

0

Dzwonisz pod numer performSelector:withObject:withObject:afterDelay:, ale ta metoda nie istnieje.

Twoja jedyna opcja to performSelector:withObject:withObject:, ale nie możesz określić opóźnienia dla tej metody. Jeśli potrzebujesz opóźnienia, prawdopodobnie musisz utworzyć kategorię dla NSObject i samodzielnie utworzyć nową metodę.

4

Klasa NSObject ma metodę performSelector:withObject:afterDelay:, a protokół NSObject określa metodę performSelector:withObject:withObject:, ale nigdzie nie określono wartości performSelector:withObject:withObject:afterDelay:.

W takim przypadku należy użyć funkcji NSInvocation, aby uzyskać pożądaną funkcjonalność. Skonfiguruj wywołanie, a następnie możesz wywołać performSelector:withObject:afterDelay w samym wywoływaniu, używając selektora invoke i obiektu nil.

1

To nie jest dobry sposób, aby dostać się wokół niego, ale jeśli chciałeś można zmodyfikować metodę przyjąć NSArray, gdy obiekt o indeksie 0 jest przycisk, a na indeks 1 to ciąg.

3

Nie ma metody wykonywania selektora z wieloma argumentami: i z opóźnieniem. Można owinąć przycisk i obiektu String w NSDictionary obejść to tak:

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

Jeśli kierujesz iOS 4.0+ można używać bloków. Coś na wzór tego powinno wystarczyć.

// 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

Będę o tym pamiętał, ale celuję w 3.0. – jarryd

+0

W takim przypadku należy użyć metody NSInvocation dostarczonej przez innych. Bloki zostały wprowadzone tylko w iOS 4.0. – extremeboredom

Powiązane problemy