Objective C is a very flexible language, but one thing which I have always found missing is a native way to have private methods. I find private methods extremely useful when separating internal logic in a class into reusable methods which are irrelevant outside the scope of that class.
Before I continue, it’s worth noting that due to the nature of Obj C, true private methods aren’t really possible. Never the less, we can simulate them pretty well.
Here is a very basic class which we will be adding a private method to:
#import "BasicClass.h" @implementation BasicClass @end
As you (hopefully) already know, Objective C separates the header (.h) files from the implementation (.m) of that class. With Objective C, you can send any message to any class so technically, you could just create a method in the implementation of a class without putting it in the header, and send a message to this object when we need to use it.
Lets add a private method called secretMethod to our class. We simply add it to the implementation file and leave it out of the header file.
#import "BasicClass.h"
@implementation BasicClass
// a secret method
- (void)secretMethod {
}
@end
From any other method in the BasicClass, we could now simply send a message to the secret message as follows:
[self secretMethod];
This works great, so I guess we are done? No! it gives a compiler warning… and nobody wants compiler warnings! It also doesn’t auto-complete within Xcode which also sucks.
Solution – Use a Class Extension
#import "BasicClass.h"
@interface BasicClass()
- (void)secretMethod;
@end
@implementation BasicClass
// a secret method
- (void)secretMethod {
}
@end
What we have essentially done here is used a private category to add the secretMethod to BasicClass, but inside the implementation file. This means things now compile without warnings AND auto-complete inside Xcode but without revealing this fact within our header file.
Using a Class Extension instead of an internal named Category e.g. @interface (Private) also gives us the advantage of being warned by the compiler if we don’t implement the secretMethod.
Hope this helps and thanks to those who commented about using a Class Extension instead of named Category! I’ve updated both this blog post and my knowledge!
Cheers,
Andrew




December 22, 2011 at 4:44 pm
Apple recommends to give no name to private categories.
So it will look like:
@interface BasicClass()
- (void)secretMethod;
@end
December 22, 2011 at 4:47 pm
You should use a class extension instead of a category:
@interface BasicClass()
- (void)secretMethod;
@end
Class extensions exist for this purpose and as a benefit the compiler will warn you if you do not implement the secretMethod method in the @implementation block.
December 22, 2011 at 4:50 pm
Through a couple IRC conversations and some time trying to work out a good way to share private methods and ¡properties! in categories, I came to the habit of putting my class extension in a header file and using that as Private.