- Introspection
- Protocols
- Extending Classes
- Informal Protocols
- Second-Chance Dispatch
- Summary
Extending Classes
One things in Objective-C that has no direct analog in C++ is the idea of a category—a collection of methods that are added to an existing class. Once the category is loaded, they have no difference from other methods. Categories, like classes, are declared with an interface and an implementation.
Category interfaces can be used without a corresponding implementation to expose other methods, giving something like a friend class in C++. If you implement methods in a class, but don't declare them in an interface, you'll get a compile-time warning when you use them. You can create a category interface like this:
@interface AnObject (Private) - (void) privateMethod; @end
If you put this at the top of your implementation file, you won't get a compile-time warning when you send a -privateMethod message to instances of AnObject. The name in parentheses (Private) is just the name of the category. This can be anything. Note that, without an @implementation section, this is just like a C forward declaration of a function. If there's no corresponding function implementation in C, you'll get a linker error. If there's no corresponding method implementation in Objective-C, you'll get a runtime exception.
You can provide extra method implementations using a category in exactly the same way as when you provide "normal" methods:
@implementation AnObject (NewMethods) - (void) newMethod { ... } @end
If you send a -newMethod message to any instance of AnObject, this method will be called. You can also use this to replace existing methods in an object with your own version, so you don't need access to the source code for the object in question. This approach is often used to instrument various methods in library classes, but can also be used to patch bugs in third-party libraries for which you don't have the source code.
One of the less-documented parts of categories is that categories allow you to add conformance to protocols to existing objects. If your category adopts a protocol, you'll get a compile-time warning if you don't provide implementations for every method, and will be able to do runtime tests to check for conformance. We use this facility in Étoilé to add conformance to a collection protocol to all of the collection classes in Foundation, giving them a consistent interface.