0

我需要将 touchesBegan 中的触摸和事件传递给我自己的由 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' 许多不响应'-target'

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

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

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

谢谢你的帮助。

4

2 回答 2

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;
    }
}

也许我误解了你的意图,但似乎你让这种方式变得比它需要的更复杂。

于 2011-02-13T18:41:34.180 回答
0

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

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

使用您当前的代码,您要求targetself. 您可能不想这样做 - 我假设您希望您的调用仅在self. 在这种情况下,使用这个:

[inv performSelector:@selector(invokeWithTarget:) withObject:self afterDelay:.5];
于 2011-02-13T18:39:04.947 回答