Reputation: 985
In my app I have an animation that scrolls across the screen. My problem is that when I use an @selector
to call my animation the thread crashes.
If I use the same @selector
to call another function in my page it works perfect but when call this function it doesn't seem to work. If I put my code in the viewDidLoad
section it works fine.
I tried quite a few of these links for unrecognized selector sent to instance
in Stackoverflow but nothing helped. I also tried - (void)imageSpawn
instead of - (void) imageSpawn:(id)sender withEvent:(UIEvent *)
event and change the selector to (imageSpawn)
instead of `(ImageSpawn:) still no luck....
- (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)
Upvotes: 0
Views: 952
Reputation: 9836
- (void)viewDidLoad
{
[self performSelector:@selector(imageSpawn:withEvent:) withObject:nil withObject:nil];
}
Your method defination contains two parameter - (void) imageSpawn:(id) sender withEvent:(UIEvent *) event
, so you need to call method with two parameters in selector.
NOTE
If you want to pass two object to selector then another method is available that is performSelector:withObject:withObject:
Which Sends a message to the receiver with two objects as arguments.
Example
[self performSelector:@selector(imageSpawn:withEvent:) withObject:senderObject withObject:eventObject];
So ideally you should use above method for two parameter parsing or encapsulate the data you want to send along into some single Objective C object (e.g. a NSArray, a NSDictionary, some custom Objective C type) and then pass it through the[NSObject performSelector:withObject:afterDelay:]
Example
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];
Upvotes: 1
Reputation: 539745
- (void) imageSpawn:(id) sender withEvent:(UIEvent *) event
is a method with 2 arguments, and its selector is
@selector(imageSpawn:withEvent:)
However,
performSelector:withObject:afterDelay:
must only be used with methods that have zero or one argument. So you can either replace your method by
- (void) imageSpawn:(id) sender
and call
[self performSelector:@selector(imageSpawn:) withObject:nil afterDelay:3];
or use GCD methods:
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];
});
The advantage is much better argument and type checking.
Upvotes: 2