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
Apple recommends to give no name to private categories.
So it will look like:
@interface BasicClass()
– (void)secretMethod;
@end
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.
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.