2010-07-11 15 views
12

Yo sé de un par de reglas con respecto a las categorías de Objective-C:¿Qué sucede si dos categorías ObjC anulan el mismo método?

  1. métodos categoría no deben reemplazar los métodos existentes (clase o instancia)
  2. Dos diferentes categorías que aplican el mismo método para el mismo clase tendrá como resultado un comportamiento indefinido

me gustaría saber lo que sucede cuando puedo reemplazar uno de mis propios métodos categoría en t la misma categoría. Por ejemplo:

@interface NSView (MyExtensions) 
- (void)foo; // NSView category implementation 
@end 

@interface MyClass : NSView 
{ } 
@end 

@interface MyClass (MyExtensions) 
- (void)foo; // MyClass category implementation 
@end 

Con estas interfaces definidas, ¿qué método se ejecutará cuando ejecute el siguiente código?

MyClass * instance = [[MyClass alloc] initWith...]; 
[instance foo]; 
[instance release]; 

Nota: Con mi compilador, la implementación MyClass tiene prioridad, pero no estoy seguro de si eso se garantiza que ocurra, o simplemente un sabor específico de un comportamiento indefinido.

Respuesta

12

Cada método de cada clase tiene una implementación. Una categoría agrega o reemplaza un método para una clase específica. Eso significa que el comportamiento que está viendo, donde MyClass tiene uno foo y NSView tiene otro foo, está bien definido. Cualquier instancia de MyClass tendrá un foo diferente de cualquier instancia de NSView que no sea MyClass, como si foo se hubiera definido en la implementación principal y no en una categoría. Incluso debería poder llamar al [super foo] desde MyClass para acceder al foo definido para NSView.

+3

¿Es correcto sobrescribir en el método de Categoría declarado e implementado en Categoría de superclase? – BergP

32

Extender sobre la respuesta drawnonward:

Es cuestión de jerarquía. Las categorías son realmente solo un medio para organizar los archivos fuente. Cuando se compila, todos los métodos de una clase, incluidos los definidos en cualquier categoría, terminan en el mismo archivo.

Cualquier cosa que pueda hacer en una interfaz de clase regular que pueda hacer en una categoría y cualquier cosa que no debería hacer en una interfaz de clase regular que no debe hacer en una categoría.

Así:

métodos categoría no deben anular métodos existentes (clase o instancia)

Puede utilizar los métodos definidos en la interfaz de clase regular para anular heredaron métodos para que pueda anula los métodos heredados en una categoría.

Sin embargo, nunca intentaría tener dos definiciones idénticas de métodos en la misma interfaz ordinaria, por lo que nunca debería tener un método en una categoría que tenga el mismo nombre como método en la interfaz ordinaria u otra categoría en el misma clase. Dado que todas las definiciones de métodos terminan en el mismo archivo compilado, obviamente colisionarían.

dos categorías diferentes de aplicación las mismas método da como resultado un comportamiento indefinido

Eso debe ser reescrito para decir "Dos categorías diferentes que aplican el mismo método para la misma clase resultados en indefinido comportamiento." Una vez más, dado que todos los métodos para cualquier clase terminan en el mismo archivo, tener dos métodos en la misma clase obviamente causaría rareza.

Puede usar categorías para proporcionar métodos que anulen los métodos de superclase porque una clase y su superclase son dos clases distintas.

Si alguna vez está confundido acerca de si una categoría causará problemas simplemente pregúntese esto: "¿Funcionarían los métodos en la categoría si los copié y pegué en los archivos de la clase '.h/.m?" Si la respuesta es "sí", entonces estará limpio. Si "no", entonces tienes problemas.

+2

+1 Gracias. Esa es una muy buena forma de describirlo. También cambié la redacción de la regla n. ° 2 para que coincida con la tuya. –

Cuestiones relacionadas