Objective-C Reflections: Calling Methods By Their String Name

Today, I was making a pretty simple app to test out delegations (source code here). Basically, as you press on one of the four buttons (Magenta, Purple, Green, or Red), the background color of view behind the buttons turns the pressed color (see below):

My initial take at the method to change the background color looked like this:

- (void)changeColor:(NSString *)colorName
{
    
    if ([colorName isEqualToString:@"Green"]) {
        self.view.backgroundColor = [UIColor greenColor];
    } else if ([colorName isEqualToString:@"Red"]){
        self.view.backgroundColor = [UIColor redColor];
    } else if ([colorName isEqualToString:@"Purple"]){
        self.view.backgroundColor = [UIColor purpleColor];
    } else if ([colorName isEqualToString:@"Magenta"]){
        self.view.backgroundColor = [UIColor magentaColor];
    }

}

Obviously the above is very repetitive – the only thing that changes between the methods in the color called on the UIColor object – but it is also not scalable. Imagine if you had 50 buttons with color names! Or if you wanted to change up the color names on the buttons – you’ll have to find the previous color if statement and change it!

Good thing Objective-C has a bit of metaprogramming built in. So you can use Reflections to call the method by it’s string name! In other words, you can concatenate the color name (e.g “green”) with the word “Color”, and then call the method name “greenColor”.

Here is what my new and nicely refactored code looks like:

- (void)changeColor:(NSString *)colorName
{
    
    NSString *colorMethodName = [[colorName lowercaseString] stringByAppendingString:@"Color"];
    self.view.backgroundColor = [UIColor performSelector:NSSelectorFromString(colorMethodName)];
}

Nice, right?!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.