2011-02-13 36 views
0

我需要将touchesBegan的触摸和事件传递给由performSelector调用的我自己的方法。我正在使用NSInvocation来打包参数,但是我遇到了目标问题。如何让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目标]:无法识别的选择发送到实例0x5b39280

我必须承认,我真的不明白什么目标试图在这里做,它是如何设置的。

感谢您的帮助。

回答

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

也许我误解你的意图,但似乎你正在做这样更复杂比它需要。

+0

感谢您通过NSArray传递参数的帮助,这是难题。延迟是为了管理点击。如果在此时间内有滚动,则点击被取消。这种方法似乎工作得很好。 – iphaaw 2011-02-13 23:24:02

0

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

目标是您希望执行调用的对象。您遇到崩溃是因为您选择的对象 - [self] - 不会响应target消息。我想你可能对你需要通过的内容有点困惑。

用你现在的代码,你要求你的调用在selftarget属性上执行。你可能不想这样做 - 我会假设你想让你的调用简单地在self上执行。在这种情况下,使用这个:

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

我实际上使用了上述方法,这意味着我可以完全摆脱NSInvocation。我认为你是对的,自己会很好。 – iphaaw 2011-02-13 23:28:38