Pregunta

Trate de averiguar cómo funcionan realmente las cosas. Así que pensé cuando me sobrescribir ciertos métodos de uso de categorías, que obtendría NSLogs interesantes.

@implementation UIView(Learning)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"-hitTest:withEvent: event=%@", event);
    return [self hitTest:point withEvent:event];
}
@end

super y uno mismo no trabajo aquí. ¿Hay una manera de llamar la implementación original de -hitTest: withEvent :? Lo que quiero es un NSLog cada vez que -hitTest: withEvent:. Se llama en una UIView

Es sólo para fines personales de aprendizaje. Quiero ver el evento en acción.

¿Fue útil?

Solución

Puede hacerlo, pero no el uso de una categoría. Una categoría sustituye a un método. (Advertencia, coche analogía) Si usted tiene un coche, y se destruye el coche y reemplazarlo con un nuevo coche, se puede seguir utilizando el coche viejo? No, porque se ha ido y ya no existe. Lo mismo con las categorías.

Lo que podría hacer es usar el tiempo de ejecución de Objective-C para añadir el método con un nombre diferente en tiempo de ejecución (por ejemplo, "bogusHitTest:withEvent:"), y luego intercambiar las implementaciones de hitTest:withEvent: y bogusHitTest:withEvent:. De esta forma cuando las llamadas de código hitTest:withEvent:, que va a ejecutar el código que fue escrito originalmente para bogusHitTest:withEvent:. A continuación, puede tener ese código de invocación bogusHitTest:withEvent:, que ejecutará la implementación original.

Así que el método falsa se vería así:

- (UIView *) bogusHitTest:(CGPoint)point withEvent:(UIEvent *)event {
  NSLog(@"executing: %@", NSStringFromSelector(_cmd));
  return [self bogusHitTest:point withEvent:event];
}

El código para intercambiar los métodos sería algo a lo largo de las líneas de:

Method bogusHitTest = class_getInstanceMethod([UIView class], @selector(bogusHitTest:withEvent:));
Method hitTest = class_getInstanceMethod([UIView class], @selector(hitTest:withEvent:));
method_exchangeImplementations(bogusHitTest, hitTest);

Otros consejos

Lo que se quiere hacer es llamada swizzling método: http://www.cocoadev.com/ index.pl?MethodSwizzling

Por desgracia, no, no hay manera de llamar la implementación original de un método que se reemplaza. Una vez que se implementa en la categoría que haya eliminado el método original.

Cómo enviar el mismo mensaje a super debe trabajar en su método; se llamará al método en la superclase como normal (si hay uno).

Cómo enviar el mismo mensaje a self creará un bucle infinito, como estoy seguro de que has descubierto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top