简体   繁体   中英

C4 - Try to catch an exception when calling methods by NSString

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM