versiones guia español descargar actualizar objective-c

objective c - guia - ¿Reemplaza un método a través de la categoría ObjC y llama a la implementación predeterminada?



qgis manual (4)

Al usar categorías, puede anular los métodos de implementación con los suyos de la siguiente manera:

// Base Class @interface ClassA : NSObject - (NSString *) myMethod; @end @implementation ClassA - (NSString*) myMethod { return @"A"; } @end //Category @interface ClassA (CategoryB) - (NSString *) myMethod; @end @implementation ClassA (CategoryB) - (NSString*) myMethod { return @"B"; } @end

Llamar al método "myMethod" después de incluir la categoría nets el resultado "B".

¿Cuál es la forma más fácil para que la implementación de categoría de myMethod llame al Class A original myMethod? Tan cerca como pueda imaginar, tendrías que usar las llamadas de bajo nivel para obtener el método original de enganche para Clase A y llamar eso, pero parecía que habría una manera sintácticamente más fácil de hacer esto.


Con los sofisticados métodos de "ayuda" incluidos en ConciseKit , realmente llama a la implementación predeterminada ... extrañamente ... llamando a su implementación SWIZZLED ...

Lo configura en + (void) load , llamando a + (BOOL)swizzleMethod:(SEL)originalSelector with:(SEL)anotherSelector in:(Class)klass; , es decir,

[$ swizzleMethod:@selector(oldTired:) with:@selector(swizzledHotness:) in:self.class];

y luego en el método de swizzled ... supongamos que regresa -(id) ... puedes hacer tu travesura, o la razón por la que te estás mareando en primer lugar ... y luego, en lugar de devolver un objeto, o self , o lo que sea. .

return [self swizzledHotness:yourSwizzledMethodsArgument];

Como se explica aquí ...

En este método, parece que volvemos a llamar al mismo método, lo que provoca recidivas sin fin. Pero cuando se alcanza esta línea, los dos métodos han sido intercambiados. Entonces, cuando llamamos a swizzled_synchronize, estamos llamando al método original.

Se siente y se ve extraño, pero ... funciona. Esto le permite agregar infinitos embellecimientos a los métodos existentes, y aún así "llamar al súper" (realmente uno mismo) y cosechar los beneficios de la obra original del método ... incluso sin acceso a la fuente original.


Consulte mi artículo sobre una solución que se encuentra en la Biblioteca del desarrollador de Mac: http://codeshaker.blogspot.com/2012/01/calling-original-overridden-method-from.html

Básicamente, es lo mismo que el Método Swizzling anterior con un breve ejemplo:

#import <objc/runtime.h> @implementation Test (Logging) - (NSUInteger)logLength { NSUInteger length = [self logLength]; NSLog(@"Logging: %d", length); return length; } + (void)load { method_exchangeImplementations(class_getInstanceMethod(self, @selector(length)), class_getInstanceMethod(self, @selector(logLength))); } @end


De la lista de preguntas frecuentes de comp.lang.objective-C : " ¿Qué pasa si varias categorías implementan el mismo método? Entonces la estructura del Universo tal como lo conocemos deja de existir. En realidad, eso no es del todo cierto, pero ciertamente se causarán algunos problemas. Cuando una categoría implementa un método que ya apareció en una clase (ya sea a través de otra categoría, o la clase''implementación @ primaria ''), la definición de esa categoría sobrescribe la definición que estaba presente previamente. La definición original ya no puede ser alcanzada por el objetivo. -Código. Tenga en cuenta que si dos categorías sobrescriben el mismo método, el que se haya cargado el último "gana", que puede no ser posible predecir antes de que se inicie el código. "

De developer.apple.com : "Cuando una categoría anula un método heredado, el método en la categoría puede, como de costumbre, invocar la implementación heredada a través de un mensaje a super. Sin embargo, si una categoría anula un método que ya existía en la categoría clase, no hay forma de invocar la implementación original "


Si quieres una forma de hacer esto que involucra mucking con el objetivo-c runtime, siempre puedes utilizar el método swizzling (inserta las renuncias estándar aquí). Te permitirá almacenar los diferentes métodos como selectores arbitrariamente nombrados, luego cambiarlos a tiempo de ejecución como los necesita.