Mixing camelCase with underscores in ObjectiveC

Written by: Sergey Ilyevsky

  I’ll start with a quite common example. Let’s say we have a custom view class - SideBarView, which requires a delegate. So let’s create a protocol for it:

@protocol SideBarViewDelegate
- (void) handleMenuButtonClicked;

The protocol looks just fine for now. But let’s look at the implementation inside our view controller:

    // Some code

So what is the problem here? Well, whether you like it or not (I don’t), view controllers may be quite huge. I think it’s not rare to get a view controller with more than 1k lines. Unfortunately, it’s often hard to keep them smaller. Quite a big part of view controller’s methods are delegates implementations, i.e. methods like the above one. Looking at such a method, you would like to immediately understand what protocol it implements. There’s one known solution to this - using #pragma marks to separate delegates. It didn’t work for me - I like putting methods in a class without too much order (e.g., when I take some code out to a separate function, I prefer to have it just near the caller method). Also, the pragma line may be too high above the method you are looking at, so you have to scroll / search to find it (is there another way?). So what I do is just prepend methods names with the protocol they belong too:

@protocol SideBarViewDelegate
- (void) SideBarViewDelegate_handleMenuButtonClicked;


    // Some code

It might look weird at first, but I find this very convenient. The name is long now, and this is the reason for using the underscore symbol - it’s easy to see where the function belongs and also what it does. There’s one downside though - it’s harder to refactor the protocol now, since you have to rename all the methods. Having that said, I prefer using this “convention” and to suffer during refactoring. I use it not only for protocols, but also for enums, and even with two underscores:

typedef enum {
} SideBarView_mode;

Let’s explain the above enum. There are no namespaces in Objective C. So in order to not have conflicts (especially during linking), it’s good to prepend the enum actual name “mode” with the related class name followed by underscore to make it more readable. So I called the enum SideBarView_mode. The names inside the enum are global as well (unfortunately), so I prepend them with the enum name followed by another underscore. Not only such enums are more readable, but it’s also very easy to select the right values in intellisense popups. The same practice can be used for constants:

FOUNDATION_EXPORT NSString *const SomeClass_notification_dataReloaded;
FOUNDATION_EXPORT uint const SomeClass_maxLength;

Underscore can also be used to separate long tests names:

-(void)testIsEqual_failsOnNilObject {}
-(void)testIsEqual_failsOnDifferentTypes {}
-(void)testIsEqual_failsForDifferentValues_ofCompatibleTypes {}

Of course, this practice should not be abused - if there are more than two underscores in a name, it will probably become unreadable. And of course, (except for veryLongMethodsNames_likeInTests), it would be much better if there were namespaces. But for now, I will continue to use underscore.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.