Unlike Java and C++, Objective-C also allows you to augment the behavior of a class even if you don’t have the source code for that class. You can redefine methods in this way, but you can’t invoke super or define new instance variables(1).
This is done by redeclaring and redefining the class and associating the new declaration to a so-called category.
@interface NotMyClass (MyCategory) @class NotMyClass (MyCategory)
A very common use of categories is declaring private members. Objective C doesn’t really seem to have a qualified option for declaring private functions (and all variables appear to be private, although they’re easy to expose using properties). When we want to hide methods from other classes, we typically add an interface declaration at the top of an implementation file, like this:
@interface Foo (private) // private methods @end @class Foo // implement everything Foo, including private methods @end
Your private methods are hidden from users of Foo because a class Bar using Foo imports Foo.h, and all private methods are actually specified within Foo.o; that’s it – ‘private’ as above is just a label for your category and has no magical meaning associated with it.
Other than for declaring private functions, you surely don’t need to use categories and your might actually want to avoid them – yet categories do have uses:
- Often, different applications need to use the same class in different, maybe conflicting ways.
>> Many board games could take advantage of a Board class and would like to use the same data structure and basic functionality – however, different board games also require different board functionality.
Each application can define it’s uses of the class without having to change the original class definition or define a subclass. This has many advantages:- Better than ‘loading’ the class with additional methods for each game – Since we don’t change the original definition we don’t overload the class, so we avoid clutter and potential conflicts.
- Better than subclassing. We don’t need to invent a quixotic name for the subclass.
- Better than delegating. In many object idioms, delegation is often a good alternative to inheritance. However, delegation fragments object definitions and makes designs (and code) harder to understand.
- Sometimes, you want to add the same or related functionality to several classes long after you defined the original classes.
- Keeping related functionality in a designated ‘category file’ can improve the design of your application. In this respect you might read that categories allow ‘scattering’ a class implementation. While that doesn’t sound terribly helpful, categories really allow you to keep together functionality that cuts across classes, and that is helpful.
Categories should be used carefully – especially in a team environment and when functions are overridden – as using categories might actually obfuscate your code.


Comments