I'm trying to make a presentation app and I've built some methods that put objects onto the canvas. What I'd like to do is use string concatenation to call the methods (each named after their slide index). When I call a method using runMethod
it will crash if I call a method that doesn't exist. I tried to wrap this in a try/catch/final structure and yet the app still crashes.
NSString * slidename = [NSString stringWithFormat:@"showSlide%d", counter];
@try {
[self runMethod:slidename afterDelay:0];
}
@catch (NSException *exception) {
NSLog(@"Exception: %@", exception);
}
@finally {
}
You're close. What's missing is the ability to check if the method exists before trying to run it, then catch any exception.
C4's runMethod
is a wrapper around NSObject
's performSelector
, it hides working with selectors by requiring a string as the name of the method instead of passing a selector. In your case, you really want to be looking for selectors to determine if you can run the method.
The following works:
-(void)setup {
NSArray *methodNames = @[@"aMethod",@"method2",@"anotherMethod"];
for(int i = 0; i < methodNames.count; i++) {
NSString *currentMethod = methodNames[i];
if ([self respondsToSelector:NSSelectorFromString(currentMethod)]) {
[self runMethod:currentMethod afterDelay:0];
} else {
C4Log(@"does not respond to %@",currentMethod);
}
}
}
-(void)aMethod{
C4Log(NSStringFromSelector(_cmd));
}
-(void)anotherMethod{
C4Log(NSStringFromSelector(_cmd));
}
The output of this is:
[C4Log] does not respond to method2
[C4Log] aMethod
[C4Log] anotherMethod
What also might be happening in your case is that the try-catch is actually not passing an exception because runMethod
is actually executing just fine.The delay puts the execution of the method you're running onto the next run loop and that's when it is actually failing.
You could also try:
NSString * slidename = [NSString stringWithFormat:@"showSlide%d", counter];
@try {
[self performSelector:NSSelectorFromString:(slidename)];
}
@catch (NSException *exception) {
NSLog(@"Exception: %@", exception);
}
@finally {
}
Which should execute that method immediately.