iosobjective-cuiappearancerespondstoselector

How to test Selectors on proxy-objects in Objective-C?


Is there any way to test selectors/methods when all you have is a proxy object?

/* Proxy which may forward
 * the method to some other object */ 
id proxy = [UINavigationBar appearance];

/* This condition returns FALSE
 * despite the fact that the method would have otherwise been
 * successfully executed at its destination */
if([proxy respondsToSelector:@selector(setBarTintColor:)]){
    [proxy setBarTintColor:color];
}

Solution

  • Apparently you cannot.

    The methods suggested by other answers will break easily, here's an example:

    Therefore the following code

    if([[UINavigationBar class] instancesRespondToSelector:@selector(setTranslucent:)]) {
        [[UINavigationBar appearance] setTranslucent:NO]; // BUM!
    }
    

    will result in a crash.

    The only information about which selectors conform to UIAppearance seems to be the UI_APPEARANCE_SELECTOR macro, which is stripped at compile-time.

    A runtime check doesn't look to be feasible.


    For the sake of completeness, here's an awful (but practical) way of doing it.

    @try {
        [[UINavigationBar appearance] setTranslucent:YES];
    } @catch (NSException *exception) {
        if ([exception.name isEqualToString:@"NSInvalidArgumentException"])
            NSLog(@"Woops");
        else
            @throw;
    }
    

    However, this is very fragile since there's no guarantee that you're catching only the case in which the selector doesn't conform to UIAppearance.