@selector - 有多个参数?

时间:2010-02-19 15:57:24

标签: objective-c

我今天第一次使用@selector并且无法弄清楚如何执行以下操作?如果您有多个参数,您会如何编写@selector

没有参数:

-(void)printText {
    NSLog(@"Fish");
}

[self performSelector:@selector(printText) withObject:nil afterDelay:0.25];

单一论点:

-(void)printText:(NSString *)myText {
    NSLog(@"Text = %@", myText);
}

[self performSelector:@selector(printText:) withObject:@"Cake" afterDelay:0.25];

两个论点:

-(void)printText:(NSString *)myText andMore:(NSString *)extraText {
    NSLog(@"Text = %@ and %@", myText, extraText);
}

[self performSelector:@selector(printText:andMore:) withObject:@"Cake" withObject:@"Chips"];

多个参数:(即超过2个)

NSInvocation

9 个答案:

答案 0 :(得分:36)

 - (id)performSelector:(SEL)aSelector
           withObject:(id)anObject  
           withObject:(id)anotherObject

来自Documentation

  

此方法与performSelector:相同,只是您可以为aSelector提供两个参数。 aSelector应该标识一个可以采用id类型的两个参数的方法。对于具有其他参数类型和返回值的方法,请使用NSInvocation

所以在你的情况下你会使用:

[self performSelector:@selector(printText:andMore:)
           withObject:@"Cake"
           withObject:@"More Cake"]

答案 1 :(得分:17)

当您有两个以上参数时,作为NSInvocation的替代方法,您可以使用NSObject的-methodForSelector:,如以下示例所示:

SEL a_selector = ...
Type1 obj1 = ...
Type2 obj2 = ...
Type3 obj3 = ...
typedef void (*MethodType)(id, SEL, Type1, Type2, Type3);
MethodType methodToCall;
methodToCall = (MethodType)[target methodForSelector:a_selector];
methodToCall(target, a_selector, obj1, obj_of_type2, obj_of_type3);

答案 2 :(得分:14)

我遇到了一个问题,我需要使用afterDelay以及我的@selector方法的多个参数。解?使用包装函数!

说这是我想要传递给@selector的函数:

-(void)myFunct:(NSString *)arg1 andArg:(NSString *)arg2 andYetAnotherArg:(NSString *)arg3;

显然,我甚至不能在这里使用withObject: withObject:,所以,制作一个包装器!

-(void)myFunctWrapper:(NSArray *)myArgs {
    [self myFunct:[myArgs objectAtIndex:0] andArg:[myArgs objectAtIndex:1] andYetAnotherArg:[myArgs objectAtIndex:2]];
}

并通过执行以下操作:

NSArray *argArray = [NSArray arrayWithObjects:string1,string2,string3,nil];
[self performSelector:@selector(myFunctWrapper:) withObject:argArray afterDelay:1.0];

这样我可以有多个参数使用带延迟的选择器。

答案 3 :(得分:5)

@selector(printText:andMore:)

答案 4 :(得分:4)

[self performSelector:@selector(printText:andMore) withObject:@"Cake" withObject:@"More Cake"];

答案 5 :(得分:4)

另一种选择是使用更短的语法:

#import <objc/message.h> // objc_msgSend
...
((void (*)(id, SEL, Type1, Type2, Type3))objc_msgSend)(target, a_selector, obj1, obj_of_type2, obj_of_type3);

答案 6 :(得分:2)

阐述Ben-Uri's answer,可写得更短。

E.g。调用UIView方法- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view即可 完成如下:

SEL selector = @selector(covertPoint:toView:);
IMP method = [viewA methodForSelector:selector];
CGPoint pointInB = method(viewA, selector, pointInA, viewB);

答案 7 :(得分:1)

正如KennyTM所指出的,选择器语法是

@selector(printText:andMore:)

你用

来调用它
performSelector:withObject:withObject. 

...如果您需要更多参数或不同类型,则需要使用NSIvocation

答案 8 :(得分:0)

使用指定的 NSInvocation ,您可以创建要实现的NSObject类别

DoCmd.OpenReport "My Report", acViewNormal, , "Year(MyDateField)=" & year & " AND Month(MyDateField)=" & month

类似的东西:

- (void)performSelector:(SEL)aSelector withObjects:(NSArray *)arguments;

来自:iOS - How to implement a performSelector with multiple arguments and with afterDelay?