11.6 Categories

Similar to class helpers in Object Pascal, Objective-C has Categories. Categories allow to extend classes without actually creating a descendant of these classes. However, Objective-C categories provide more functionality than a helper class:

  1. In Object Pascal, only 1 helper class can be in scope (the last one). In Objective C, multiple categories can be in scope at the same time for a particular class.
  2. In Object Pascal, a helper method cannot override a method present in the original class. In Objective-C, a category can also replace existing methods in another class rather than only add new ones. Since all methods are virtual in Objective-C, this also means that this method changes for all classes that inherit from the class in which the method was replaced (unless they override it).
  3. Object Pascal helpers cannot be used to add interfaces to existing classes. By contrast, an Objective-C category can also implement protocols.

The definition of an objective-C class closely resembles a protocol definition, and is started with the objccategory keyword:

_________________________________________________________________________________________________________
Category type

 --objccategory -|---------------------------------|-------
                -external--|---------------------- heritage-
                         -name - string constant-
----category method list --end ----------------------------------------

--heritage -(- Objective Class type identifier|protocol type identifier-- )-----
                                     ---------, ----------

--category method list|--method definition----------------------------
                   |                 -reintroduce -|  |
                   |--------------------------------|
___________________________________________________________________

Note again the possibility of an alias for externally defined categories: objective-C 2.0 allows an empty category name. Note that the reintroduce modifier must be used if an existing method needs not to be overridden, but replaced.

When replacing a method, calling ’inherited’ will not call the original method of the class, but instead will call the parent class’ implementation of the method.

The following is an example of a category definition:

MyProtocol = objcprotocol  
  procedure protocolmethod; message ’protocolmethod’;  
end;  
 
MyCategory = objccategory(NSObject,MyProtocol)  
  function hash: cuint; reintroduce;  
  procedure protocolmethod; // from MyProtocol.  
  class procedure newmethod; message ’newmethod’;  
end;

Note that this declaration replaces the Hash method of every class that descends from NSObject (unless it specifically overrides it).