如何让performSelector使用NSInvocation?
我需要将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
我必须承认,我真的不明白什么目标试图在这里做,它是如何设置的。
感谢您的帮助。
我认为您需要花一些时间仔细阅读您的代码,逐行。
[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;
}
}
也许我误解你的意图,但似乎你正在做这样更复杂比它需要。
我必须承认我并不真正了解目标在这里做什么以及它是如何设置的。
目标是您希望执行调用的对象。您遇到崩溃是因为您选择的对象 - [self]
- 不会响应target
消息。我想你可能对你需要通过的内容有点困惑。
用你现在的代码,你要求你的调用在self
的target
属性上执行。你可能不想这样做 - 我会假设你想让你的调用简单地在self
上执行。在这种情况下,使用这个:
[inv performSelector:@selector(invokeWithTarget:) withObject:self afterDelay:.5];
我实际上使用了上述方法,这意味着我可以完全摆脱NSInvocation。我认为你是对的,自己会很好。 – iphaaw 2011-02-13 23:28:38
感谢您通过NSArray传递参数的帮助,这是难题。延迟是为了管理点击。如果在此时间内有滚动,则点击被取消。这种方法似乎工作得很好。 – iphaaw 2011-02-13 23:24:02