在我的应用程序中,我有一个滚动屏幕的动画。我的问题是,当我使用@selector
来调用我的动画时,线程会崩溃。
如果我使用相同的@selector
在我的页面中调用另一个函数,它可以完美地工作,但是当调用此函数时它似乎不起作用。如果我将代码放在viewDidLoad
部分,则可以正常工作。
我在Stackoverflow中为unrecognized selector sent to instance
尝试了很多这些链接,但没有任何帮助。我还尝试了- (void)imageSpawn
而不是- (void) imageSpawn:(id)sender withEvent:(UIEvent *)
事件,并将选择器更改为(imageSpawn)
而不是`(ImageSpawn :)仍然没有运气....
- (void)viewDidLoad {
[self performSelector:@selector(imageSpawn:) withObject:nil afterDelay:3];
}
- (void) imageSpawn:(id) sender withEvent:(UIEvent *) event
{
UIImage* image = [UIImage imageNamed:@"ae"];
UIImageView *rocket = [[UIImageView alloc] initWithImage:image];
rocket.frame = CGRectMake(-25, 200, 25, 40);
[UIView animateWithDuration:5 animations:^(){rocket.frame=CGRectMake(345, 200, 25, 40);} completion:^(BOOL finished){if (finished){
//trigger an event.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Tapped row!"
message:[NSString stringWithFormat:@"Shot"]
delegate:nil
cancelButtonTitle:@"Yes, I did!"
otherButtonTitles:nil];
[alert show];
}
}];
[myScrollView addSubview:rocket];
}
2013-03-28 10:14:31.661 shotplacementgiude001[16897:c07] -[SelectedCellViewController imageSpawn:]: unrecognized selector sent to instance 0xa159480
2013-03-28 10:14:31.663 shotplacementgiude001[16897:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SelectedCellViewController imageSpawn:]: unrecognized selector sent to instance 0xa159480'
*** First throw call stack:
(0x16b4012 0x13c1e7e 0x173f4bd 0x16a3bbc 0x16a394e 0xdbf5b3 0x1673376 0x1672e06 0x165aa82 0x1659f44 0x1659e1b 0x27157e3 0x2715668 0x305ffc 0x2c3d 0x2b65 0x1) libc++abi.dylib: terminate called throwing an exception
(lldb)
答案 0 :(得分:2)
- (void) imageSpawn:(id) sender withEvent:(UIEvent *) event
是一个带有2个参数的方法,其选择器是
@selector(imageSpawn:withEvent:)
然而,
performSelector:withObject:afterDelay:
只能与零或一个参数的方法一起使用。所以你可以用
替换你的方法- (void) imageSpawn:(id) sender
并致电
[self performSelector:@selector(imageSpawn:) withObject:nil afterDelay:3];
或使用GCD方法:
double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self imageSpawn:nil withEvent:nil];
});
优点是更好的参数和类型检查。
答案 1 :(得分:1)
- (void)viewDidLoad
{
[self performSelector:@selector(imageSpawn:withEvent:) withObject:nil withObject:nil];
}
您的方法定义包含两个参数- (void) imageSpawn:(id) sender withEvent:(UIEvent *) event
,因此您需要在选择器中调用带有两个参数的方法。
注意强>
如果要将两个对象传递给选择器,则可以使用另一种方法performSelector:withObject:withObject:
使用两个对象作为参数向接收者发送消息。
实施例
[self performSelector:@selector(imageSpawn:withEvent:) withObject:senderObject withObject:eventObject];
理想情况下,您应该使用上面的方法进行两个参数解析或将要发送的数据封装到单个Objective C对象(例如NSArray,NSDictionary,一些自定义Objective C类型)中,然后将其传递给{ {1}}
实施例
[NSObject performSelector:withObject:afterDelay:]