質問

私は物事が本当にどのように機能するかを理解しようとしています。だから、カテゴリを使用して特定の方法を上書きするとき、興味深いnslogsを得ると思いました。

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

スーパーとセルフはここでは機能しません。 -hittestの元の実装を呼び出す方法はありますか:withevent:?私が欲しいのは、毎回nslogです-hittest:withevent:uiviewで呼び出されます。

個人的な学習目的のためだけです。イベントの配信が動作しているのを見たいです。

役に立ちましたか?

解決

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

あなたができることは、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);

他のヒント

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

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

に同じメッセージを送信します super あなたの方法で動作するはずです。通常のようにスーパークラスのメソッドを呼び出します(ある場合)。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top