Domanda

I cercare di capire come le cose davvero. Così ho pensato quando avrei sovrascrivere alcuni metodi utilizzando le categorie, vorrei avere NSLogs interessanti.

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

super e sé non funzionano qui. C'è un modo per chiamare l'implementazione originale di -hitTest: withEvent :? Quello che voglio è un NSLog ogni volta -hitTest: withEvent:. È chiamato su un UIView

E 'solo per scopi personali di apprendimento. Voglio vedere il caso in azione.

È stato utile?

Soluzione

Si può fare, ma non utilizzando una categoria. Una categoria sostituisce un metodo. (Attenzione, auto analogia) Se avete una macchina, e distruggi quella macchina e sostituirlo con una nuova auto, si può ancora usare la vecchia auto? No, perché non c'è più e non esiste più. Lo stesso con le categorie.

Che cosa si potrebbe fare è utilizzare il runtime Objective-C per aggiungere il metodo con un nome diverso in fase di esecuzione (ad esempio, "bogusHitTest:withEvent:"), quindi scambiare le implementazioni di hitTest:withEvent: e bogusHitTest:withEvent:. In questo modo quando le chiamate di codice hitTest:withEvent:, sta andando per eseguire il codice che è stato originariamente scritto per bogusHitTest:withEvent:. È quindi possibile avere quel codice Invoke bogusHitTest:withEvent:, che eseguirà l'implementazione originale.

Quindi il metodo fasullo sarà simile:

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

Il codice per scambiare i metodi sarebbe qualcosa sulla falsariga di:

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

Altri suggerimenti

Che cosa si vuole fare è metodo chiamato swizzling: http://www.cocoadev.com/ index.pl?MethodSwizzling

Purtroppo, no, non c'è modo di chiamare l'implementazione originale di un metodo che si ignora. Una volta che si sceglie di implementare nella categoria aver eliminato il metodo originale.

L'invio dello stesso messaggio a super dovrebbe funzionare nel metodo; si chiamerà il metodo sul superclasse come normale (se ce n'è uno).

L'invio dello stesso messaggio a self creerà un ciclo infinito, come sono sicuro che hai scoperto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top