Una extensión de clase tiene cierta similitud con una categoría, pero solo se puede agregar a una clase para la que tiene el código fuente en tiempo de compilación (la clase se compila al mismo tiempo que la extensión de clase). Los métodos declarados por una extensión de clase se implementan en el bloque @implementation para la clase original, por lo que no puede, por ejemplo, declarar una extensión de clase en una clase de marco, como una clase Cocoa o Cocoa Touch como NSString.
La sintaxis para declarar una extensión de clase es similar a la sintaxis de una categoría y se ve así:
@interface ClassName ()
@end
Debido a que no se proporciona ningún nombre entre paréntesis, las extensiones de clase a menudo se denominan categorías anónimas.
A diferencia de las categorías normales, una extensión de clase puede agregar sus propias propiedades y variables de instancia a una clase. Si declara una propiedad en una extensión de clase, así:
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
En mi humilde opinión, es mejor pensar en las extensiones de clase como una interfaz privada para una clase. La interfaz principal (en su archivo .h) actúa como la interfaz pública que define el contrato de comportamiento de la clase con otras clases.
Use extensiones de clase para ocultar información privada
Las extensiones de clase se utilizan a menudo para ampliar la interfaz pública con propiedades o métodos privados adicionales para su uso dentro de la implementación de la propia clase. Es común, por ejemplo, definir una propiedad como de solo lectura en la interfaz, pero como lectura y escritura en una extensión de clase declarada arriba de la implementación, para que los métodos internos de la clase puedan cambiar el valor de la propiedad directamente.
Como ejemplo, la clase XYZPerson podría agregar una propiedad llamada uniqueIdentifier, diseñada para realizar un seguimiento de información como un número de seguro social en los EE. UU.
Por lo general, se requiere una gran cantidad de papeleo para tener un identificador único asignado a una persona en el mundo real, por lo que la interfaz de la clase XYZPerson puede declarar esta propiedad como de solo lectura y proporcionar algún método que solicite que se asigne un identificador, como este:
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end
Para que la clase XYZPerson pueda cambiar la propiedad internamente, tiene sentido volver a declarar la propiedad en una extensión de clase definida en la parte superior del archivo de implementación de la clase:
@property (readwrite) NSString *uniqueIdentifier;
Nota: El atributo de lectura y escritura es opcional, porque es el predeterminado. Es posible que desee utilizarlo al volver a declarar una propiedad, para mayor claridad.