7

私は物事が実際にどのように機能するかを理解しようとしています。そのため、カテゴリを使用して特定のメソッドを上書きすると、興味深いNSLogが得られると思いました。

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

スーパーとセルフはここでは機能しません。-hitTest:withEvent:の元の実装を呼び出す方法はありますか?UIViewで-hitTest:withEvent:が呼び出されるたびにNSLogが必要です。

それは個人的な学習目的のためだけです。イベント配信の様子を見たいです。

4

3 に答える 3

16

あなたはそれを行うことができますが、カテゴリーを使用することはできません。カテゴリはメソッドを置き換えます。(警告、車の例え)あなたが車を持っていて、その車を破壊して新しい車と交換した場合でも、古い車を使用できますか?いいえ、なくなってもう存在しないからです。カテゴリも同じです。

できることは、Objective-Cランタイムを使用して、実行時に別の名前でメソッドを追加し(たとえば、 " ")、とbogusHitTest:withEvent:の実装を交換することです。そうすれば、コードがを呼び出すときに、元々がのために書かれたコードが実行されます。次に、そのコードでを呼び出すことができます。これにより、元の実装が実行されます。hitTest:withEvent:bogusHitTest:withEvent:hitTest:withEvent:bogusHitTest:withEvent:bogusHitTest:withEvent:

したがって、偽のメソッドは次のようになります。

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

メソッドを交換するコードは、次のようなものになります。

Method bogusHitTest = class_getInstanceMethod([UIView class], @selector(bogusHitTest:withEvent:));
Method hitTest = class_getInstanceMethod([UIView class], @selector(hitTest:withEvent:));
method_exchangeImplementations(bogusHitTest, hitTest);
于 2010-11-28T01:18:22.157 に答える
3

あなたがしたいことはメソッドスウィズリングと呼ばれています:http://www.cocoadev.com/index.pl? MethodSwizzling

于 2010-11-28T01:17:39.550 に答える
0

残念ながら、いいえ、オーバーライドするメソッドの元の実装を呼び出す方法はありません。カテゴリに実装すると、元のメソッドが削除されます。

同じメッセージをに送信するとsuper、メソッドで機能するはずです。通常どおり、スーパークラスのメソッドを呼び出します(存在する場合)。

に同じメッセージを送信するとself、あなたが発見したと確信しているように、無限ループが作成されます。

于 2010-11-28T01:05:29.840 に答える