Objective c @选择器-具有多个参数?

Objective c @选择器-具有多个参数?,objective-c,Objective C,我今天第一次使用了@selector,但还没有弄清楚如何执行以下操作?如果有多个参数,您将如何编写@selector 无参数: -(void)printText { NSLog(@"Fish"); } [self performSelector:@selector(printText) withObject:nil afterDelay:0.25]; -(void)printText:(NSString *)myText andMore:(NSString *)extraText {

我今天第一次使用了
@selector
,但还没有弄清楚如何执行以下操作?如果有多个参数,您将如何编写
@selector

无参数:

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

[self performSelector:@selector(printText) withObject:nil afterDelay:0.25];
-(void)printText:(NSString *)myText andMore:(NSString *)extraText {
    NSLog(@"Text = %@ and %@", myText, extraText);
}

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

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

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

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

[self performSelector:@selector(printText) withObject:nil 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个)

从:

此方法与相同,只是可以为选择器提供两个参数。选择器应标识一个可以接受两个id类型参数的方法。对于具有其他参数类型和返回值的方法,请使用

因此,在您的情况下,您将使用:

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

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

@selector(printText:andMore:)
你把它叫做

performSelector:withObject:withObject. 

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

我遇到了一个问题,我需要将
afterDelay
与多个参数一起用于我的
@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];

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

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

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);
详细说明,可以写得更短

例如,调用
UIView
方法
-(CGPoint)convertPoint:(CGPoint)point to view:(UIView*)视图
可以 具体做法如下:

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

另一个选项是使用更短的语法:

#import <objc/message.h> // objc_msgSend
...
((void (*)(id, SEL, Type1, Type2, Type3))objc_msgSend)(target, a_selector, obj1, obj_of_type2, obj_of_type3);
导入//objc\u msgSend ... (无效(*)(id、SEL、类型1、类型2、类型3))objc_msgSend(目标、a_选择器、obj1、类型2的obj_、类型3的obj_);
使用指定的NSInvocation可以创建实现的NSObject类别

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

- (void)performSelector:(SEL)aSelector withObjects:(NSArray *)arguments
{
    NSMethodSignature *signature = [self methodSignatureForSelector: aSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: signature];
    [invocation setSelector: aSelector];

    int index = 2; //
    for (NSObject *argument in arguments) {
        [invocation setArgument: &argument atIndex: index];
        index ++;
    }
    [invocation invokeWithTarget: self];
}

发件人:

谢谢,但我如何指定参数@“蛋糕”和@“更多蛋糕”?更新以反映答案,感谢所有帮助,非常感谢。您的“双参数”没有延迟存在
-性能选择器:withObject:withObject:
-性能选择器:withObject:afterDelay:
,但两者的混合并不存在,你是对的。我在复制/粘贴时出错了。好的,这正是我要找的。我需要能够通过引用传入参数,但不知道如何使用performSelector来实现。我确实用NSInvocation解决了这个问题,但我一直收到malloc错误。这正是我需要它做的。那些你调用函数的东西实际上被称为方法。不仅在Objective-C中,而且在所有严肃的编程语言中都有这种区别。准确地说:一旦这个东西被附加到一个对象上,它就是一种方法。单独使用时,它被称为函数。对于一般情况,我倾向于使用字典来传递参数。您不依赖于订单,并且可以很容易地拥有可选的PARM等。基于此,所以post()如果启用了ARC,您将有这样的内存问题。
- (void)performSelector:(SEL)aSelector withObjects:(NSArray *)arguments
{
    NSMethodSignature *signature = [self methodSignatureForSelector: aSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: signature];
    [invocation setSelector: aSelector];

    int index = 2; //
    for (NSObject *argument in arguments) {
        [invocation setArgument: &argument atIndex: index];
        index ++;
    }
    [invocation invokeWithTarget: self];
}