如何让performSelector与NSInvocation一起使用?

时间:2011-02-13 18:31:40

标签: iphone nsinvocation

我需要将touchesBegan中的touches和事件传递给我自己的performSelector调用的方法。我正在使用NSInvocation打包参数,但我遇到目标问题。

我这样做的原因是我可以处理其他滚动事件。

这是我的代码:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{           
    UITouch *theTouch = [touches anyObject];

    switch ([theTouch tapCount]) 
    {
        case 1:
            NSInvocation *inv = [NSInvocation invocationWithMethodSignature: [self methodSignatureForSelector:@selector(handleTap: withEvent:)]];
            [inv setArgument:&touches atIndex:2];
            [inv setArgument:&event atIndex:3];
            [inv performSelector:@selector(invokeWithTarget:) withObject:[self target] afterDelay:.5];
            break;
    }
}

其中handleTap定义为:

-(IBAction)handleTap:(NSSet *)touches withEvent:(UIEvent *)event 
{
    [super touchesBegan:touches withEvent:event];
}

我的问题是,当我编译它时,我收到警告:

' CategoryButton'许多人没有回应“目标”

当我运行它时,它崩溃了:

- [CategoryButton target]:无法识别的选择器发送到实例0x5b39280

我必须承认,我并不真正了解目标在这里尝试做什么以及如何设置。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

我认为你需要花一些时间仔细阅读你的代码。

[inv performSelector:@selector(invokeWithTarget:) withObject:[self target] afterDelay:.5];

这不符合您的想法。执行此方法后半秒钟,将发生这种情况:

[inv invokeWithTarget:[self target]];

首先,您的班级CategoryButton没有名为target的方法。第二,为何延迟?如果您使用这些触摸滚动,延迟0.5秒将对用户来说非常痛苦。

为什么要使用NSInvocation类?如果您真的需要延迟,只需在performSelector:实例上使用CategoryButton方法:

NSArray *params = [NSArray arrayWithObjects:touches, event, nil];
[self performSelector:@selector(handleTap:) withObject:params afterDelay:0.5];

请注意performSelector:方法只支持一个参数,因此必须将它们包装在NSArray中。 (或者,您可以使用NSDictionary。)

您必须更新handleTap:方法以接受NSArray / NSDictionary并根据需要获取参数。

但是,如果你不需要延迟,为什么不自己调用这个方法:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{           
    UITouch *theTouch = [touches anyObject];

    switch ([theTouch tapCount]) 
    {
        case 1:
            [super touchesBegan:touches withEvent:event];
        break;
    }
}

也许我误解了你的意图,但似乎你做的比这更复杂。

答案 1 :(得分:0)

  

我必须承认我并不真正了解目标在这里尝试做什么以及如何设置。

目标是您希望对其执行调用的对象。您遇到了崩溃,因为您选择的对象 - [self] - 没有响应target消息。我想你可能只是对你需要传递的内容感到困惑。

使用当前代码,您要求在target self属性上执行调用。您可能不想这样做 - 我认为您希望仅在self上执行您的调用。在这种情况下,请使用:

[inv performSelector:@selector(invokeWithTarget:) withObject:self afterDelay:.5];