0

在我的应用程序中,我有一个在屏幕上滚动的动画。我的问题是,当我使用 an@selector调用我的动画时,线程崩溃了。

如果我使用相同@selector的方法在我的页面中调用另一个函数,它可以完美运行,但是当调用这个函数时它似乎不起作用。如果我将代码放在该viewDidLoad部分中,它可以正常工作。

unrecognized selector sent to instance我在 Stackoverflow中尝试了很多这样的链接,但没有任何帮助。我也尝试- (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) 
4

2 回答 2

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

优点是更好的参数和类型检查。

于 2013-03-28T08:49:04.637 回答
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 类型)中,然后通过[NSObject performSelector:withObject:afterDelay:]

例子

NSDictionary *dictionary = [[NSDictionary alloc] init];
[dictionary setObject:senderObject forKey:@"sender"];
[dictionary setObject:eventObject forKey:@"event"];
[self performSelector:@selector(imageSpawn:withEvent:) withObject:dictionary afterDelay:3.0];
于 2013-03-28T08:40:02.810 回答