Tu pots afegir mètodes a una classe declarant-los en un fitxer d'interficies sota el nom de categoria i definint-los en el fitxer d'implementació sota el mateix nom. El nom categoria indica que els mètodes són afegits a una classe declarada en una altre lloc, no en una classe nova. Tu no pots, de cap manera, utilitzar una categoria per afegir variables adicionas a la classe.
Una categoria pot ser una alternativa a una subclasse. Ja que defineix ua subclasse extesa d'una classe existent, a través d'una categoria pots afegir mètodes a la classe directament. Per exemple, pots afegir categories a NSArray i altres classes Cocoa. Com en el cas d'una subclass, no necessites el codi font per que la classe d'extengui.
Els mètodes de categoria són afegits a la part convertida del tipus de classe. Per exemple, els mètodes afegits a la classe NSArray en una categoria están entre els mètodes que el compilador espera que tingui una instància de NSArray en el seu repertori. Els mètodes afegits en una subclasse de la classe NSArray no són inclosos en el tipus NSArray. (Això passa només en objectes marcats estàticament, la marcació estàtica és l'una forma que el compilador pot conneixer la classe d'un objecte).
Els mètodes de categoria poden fer qualsevol cosa que els mètodes definits en la pròpia classe poden fer. En temps d'execució, no hi ha diferència. Els mètodes de categoria afegeixits a la classe són heredats per totes les subclasses de la classe, tal com els altres mètodes.
La declaració d'una categoria d'interficie és molt semblant a la declaració d'una interficie de classe -- excepte que el nom de categoria hi es mencionat entre parèntesis després del nom de la classe i la superclasse no és mencionada. Excepte que el mètode no accedeixi a cap variable de la classe, la categoria ha de importar el fitxer de la interficie per la classe que extén:
#import "ClassName.h"
@interface ClassName ( CategoryName )
method declarations
@end
La implementació, com és normal, importa la seva pròpia interficie. Asumint que el fitxer d'interficie és anomenat després de la categoria, una implementació de categoria seria semblant a això:
#import "CategoryName.h"
@implementation ClassName ( CategoryName )
method definitions
@end
Fixeu-vos que una categoria no pot declarar variables adicionas per la classe; només mètodes. Tanmateix, totes les variables dins l'abast de la classe estan també dins l'abast de la categoria. Aquest inclou totes les variables declarades per la classe, fins hi tot les declarades @private.
No hi ha límit al nombre de categories que pots afegir a una classe, però cada nom de categoria ha de ser diferent, i cadascun ha de declarar i definir un conjunt de mètodes diferents.
Els mètodes afegits en una categoria poden utilitzar-se per extendre la funcionalitat de la classe o sobreescriure els mètodes que la classe hereda. Una categoria també pot sobreescriure mètodes declarats en la interfície de la classe. Tanmateix, no és posible sobreescriure mètodes declarats en altres categories de la mateixa classe. Una categoria no és un substitut de una subclasse. És millor si les categories no intenten redefinir mètodes que estan explícitament declarats en la secció de la classe @interface. Fixeu-vos també que una classe no pot definir el mateix mètode més d'un cop.
Quan una categoria sobreescriu un mètode heredat, la nova versió pot, com és normal, incorporar la versió heredada a través d'un missatge a super. Però no hi ha manera per un mètode d'una categoria incorporar un mètode amb el mateix nom definit per la mateixa classe.
Les categories poden utilitzar-se per extendre classe definides per altres implementadors --per exemple, pots afegir mètodes a les classes definides en el marc de treball Cocoa. Els mètodes afegits són heredats per les subclasses i són indistingibles en temps d'execució amb els mètodes originals de la classe.
Les categories també poden utilitzar-se per distribuir la implementació d'una nova classe dins de fitxers de code separats --per exemple, podries agrupar els mètodes d'un classe gran dins de varies categories i possar cada categoria en un fitxer diferetn. Quan les uses així, les categories poden beneficiar al desenvolupament del procés en varies vies:
Les categories també s'utilitzem per declarar protocols informas, que estan tractats a "Protocols -- Declarant Interficies per que Altres les Implementin".
Una categoria pot afegir mètodes a qualsevol classe, inclosa la classe arrel. Els mètodes afegits a NSObject aconsegueix que estiguis disponibles per totes les classes que estan enllaçades en el teu codi. Mentre això pot pugui utilitzar-se normalment, això pot ser una mica perillós. Encara que pot semblar que en les modificacions de la categoria s'entenen bé i d'impacte limitat, la herència els hi dona un abast més ampli. Pots realitzar cambis involuntaris a les classes que no veus; pots no conneixer totes les conseqüències del que estas fent. Per altra banda, altres que no són concients dels teus canvis no poden entendre que estan fent.
A demés, hi ha dos altres consideracions per mantindre en ment quan d'implementen mètodes de la classe arrel:
super són invàlid (no hi ha superclasse).Normalment, els objectes classe poden executar només mètodes de classe. Però instanciar mètodes definis en la classe arrel són un cas especial. Aquests defineixen una interficie al sistema d'execució que tots els objectes herede. Els objecte de classe són completament correctes i necessiten compartir la mateixa interfície.
Aquesta carecterísitca implica que necessites considerar la posibilitat que un mètode del que estas definint en una categoria de la classe NSObject es va poder realitzar també pels objectes de la classe. Per exemple, dins del cos del mètode, un mateix pot ser tant un objecte de classe així com un instància. Mireu la especificació de la classe NSObjecte en el marc de treball de referència de la Fundació per més informació sobre l'accés de la classe als mètodes de la instància arrel.