
Objective-C is an incredibly flexible language, but there are a few things I don’t think it handles very elegantly — private methods are one of those things. Private methods are important when designing your classes — keeping the implementation of your methods separate to the interface that users of your class see is good practice, and lets you change the way you implement things in future without making users of your class change their code.
Objective-C has a great feature known as categories. In the words of Scott Stevenson, “a category allows you to add methods to an existing class without subclassing it or needing to know any of the details of how it’s implemented”. My private methods are implemented using an anonymous category on each class. These are also known as “Class Extensions” and they look like this in my .m file:
#import "MyGreatClass.h"
@interface MyGreatClass ()
- (void)MyGreatClass_somePrivateMethod;
@end
#pragma mark -
@implementation MyGreatClass
// Your standard methods for the class go here.
#pragma mark -
#pragma mark Private methods
- (void)MyGreatClass_somePrivateMethod {
// Implement your private method here.
}
@end
By declaring the method interface inside the class extension, rather than in your header, subclasses and users of your class cannot see the method, and thus can’t use it. However within an instance of your class, the method is still usable!
You’ll notice that I preface my private methods with the name of the current class — I do this to avoid method name collisions with subclasses. It’s not strictly necessary, but it means I don’t have to think as hard when implementing subclasses of my class.
You can do everything you would in a normal class except declare new instance variables. I often use my class extensions to redeclare a public readonly property as readwrite within the confines of the class instance. Another common use in my code are the following two methods:
- (void)MyGreatClass_registerObservers;
- (void)MyGreatClass_unregisterObservers;
These methods are used to set up and tear down any Key/Value Observers and bindings for the current class. I use these so often that I’ve put together an Xcode class template so that they are included in my classes by default.
Please keep in mind that Objective-C has no true implementation of private methods — other classes can use these “private” methods if they know the structure of the method in question. With that said, I still believe this is a great way to keep your implementation as clean as possible.
Update
Both Paul and Collin make good points in the comments — you can just declare your private methods inline in your class without using an anonymous category. That will work so long as the declaration occurs before the first use of the method. In my mind, there are two good reasons to use a category:
- Readability/cleanliness — I find it a lot easier to group the declarations for my private methods together inside the category block. It’s quite readable and means I can just look at the start of the source for each of my classes to see what private methods are defined;
- It’s the same when compiled — as I understand it, anonymous categories are compiled into the same space as the methods for the class they are defined for. Functionally — once the code is compiled — there shouldn’t be any difference between the two ways of defining the methods.
Comments
Posted by Paul on
Posted by Collin on
Posted by Rob Rix on
Sorry, this conversation has finished.
This post is a bit old now, so I've closed the conversation. If you're keen to keep talking about it, please email me directly.