Anulación de métodos usando categorías en Objective-C

87

¿Puedo usar una categoría de clase para anular un método que ya está implementado usando una categoría? Me gusta esto:

1) Método original

-(BOOL) method {
  return true;
}

2) Método anulado

-(BOOL) method {
  NSLog(@"error?"); 
  return true; 
}

¿Funcionará esto o es ilegal?

retix
fuente

Respuestas:

146

De la documentación de Apple :

Aunque el lenguaje Objective-C actualmente le permite usar una categoría para anular los métodos que la clase hereda, o incluso los métodos declarados en la interfaz de la clase, no se recomienda hacerlo . Una categoría no sustituye a una subclase. Existen varias deficiencias importantes en el uso de una categoría para anular métodos:

  • Cuando una categoría anula un método heredado, el método de la categoría puede, como de costumbre, invocar la implementación heredada mediante un mensaje a super. Sin embargo, si una categoría reemplaza un método que existe en la clase de la categoría, no hay forma de invocar la implementación original .

  • Una categoría no puede anular de manera confiable los métodos declarados en otra categoría de la misma clase.

    Este problema es de particular importancia porque muchas de las clases de Cocoa se implementan mediante categorías. Es posible que un método definido por el marco que intente anular se haya implementado en una categoría, por lo que no se define qué implementación tiene prioridad.

  • La sola presencia de algunos métodos de categoría puede provocar cambios de comportamiento en todos los marcos. Por ejemplo, si anula el windowWillClose:método de delegado en una categoría en NSObject, todos los delegados de ventana en su programa responden usando el método de categoría; el comportamiento de todas sus instancias de NSWindow puede cambiar. Las categorías que agrega en una clase de marco pueden causar cambios misteriosos en el comportamiento y provocar bloqueos.

Benoît
fuente
Gracias pero eso ya lo sé. Me pregunto si mi caso es legal o no. Mi caso se diferencia un poco de los documentos. :)
retix
¿Por qué es diferente? El documento dice que es legal SI el método original no está en una categoría, pero se desaconseja fuertemente. Entonces puedes hacerlo ...
Benoît
1
Gracias por tu consejo. Soy pobre en este idioma. Recibí nueva información tuya.
retix
1
¿Es correcto anular el método de categoría declarado e implementado en la categoría de superclase?
BergP
2
El enlace está roto, ¿es esta la nueva versión? developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
RndmTsk
9

El enlace de documentación anterior está muerto; El mejor reemplazo que pude encontrar fue aquí: Apple Docs :

Evite los enfrentamientos de nombres de métodos de categorías

Debido a que los métodos declarados en una categoría se agregan a una clase existente, debe tener mucho cuidado con los nombres de los métodos.

Si el nombre de un método declarado en una categoría es el mismo que un método en la clase original, o un método en otra categoría en la misma clase (o incluso una superclase), el comportamiento es indefinido en cuanto a qué implementación del método se usa en tiempo de ejecución. Es menos probable que esto sea un problema si usa categorías con sus propias clases, pero puede causar problemas al usar categorías para agregar métodos a las clases estándar de Cocoa o Cocoa Touch.

Es Apple usando un toque más ligero, pero el punto principal es el mismo: invitas al desastre, porque el comportamiento impredecible es silencioso.

AmitaiB
fuente
2

Es importante tener en cuenta que una categoría también se puede usar para anular los métodos existentes en la clase base (por ejemplo, el método de conducción de la clase Car), pero nunca debe hacer esto. El problema es que las categorías son una estructura organizativa plana. Si anula un método existente en Car + Maintenance.m, y luego decide que desea cambiar su comportamiento nuevamente con otra categoría, no hay forma de que Objective-C sepa qué implementación usar. La subclasificación es casi siempre una mejor opción en tal situación.

De este tutorial, http://rypress.com/tutorials/objective-c/categories

Vinuta
fuente