6

私は物事が実際にどのように機能するかを理解しようとします。だから私はカテゴリを使って特定のメソッドを上書きすると思っていましたが、興味深い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:?の元の実装を呼び出す方法はありますか?私が欲しいのは毎回NSLogです-hitTest:withEvent:はUIViewで呼び出されます。

これは単なる学習目的のためのものです。私はイベントの配信を実際に見たいと思う。

+0

スーパーがあなたのために「のカテゴリでは動作しません:の線に沿って何かになる方法を交換する

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

コード:

だから、偽の方法は次のようになります。同じクラスでそれを呼び出すのではなく、あなたはクラスのスーパーでそれを呼んでいます。この場合、スーパーはhitTest:withEventメソッドを持たないUIResponderです。 selfを呼び出すと無限ループになります。なぜならあなたはhitTest:overEventを "self"に置き換えているからです。 –

+0

私のコメントはちょっと変わっているようですが、前のコメントが削除される前には意味がありました。 –

答えて

14

あなたはそれを行うことができますが、カテゴリを使用していない:あなたが何をしたいか

+0

素晴らしい。ショート。作品。ありがとう! –

0

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

superに同じメッセージを送信することは、あなたのメソッドでうまくいくはずです。スーパークラスのメソッドを呼び出す(存在する場合)。

selfに同じメッセージを送信すると、あなたが発見したと確信しているように、無限ループが作成されます。 http://www.cocoadev.com/index.pl?MethodSwizzling

+1

アダムは言ったように、これはこのようにはできませんが、メソッドスウィズルを見てみることができます。ここには素晴らしい例があります:http://github.com/marksands/UITextViewLinkOptions –

3

は、メソッドスウィズリングと呼ばれています。メソッドをカテゴリに置き換えます。 (警告、車の類推)もしあなたが車を持っていて、その車を破壊して新車に交換すれば、古い車を使えますか?いいえ、それはなくなってもう存在しないからです。カテゴリと同じです。あなたは何ができるか

hitTest:withEvent:bogusHitTest:withEvent:の実装を交換、その後、ランタイム(例えば、「bogusHitTest:withEvent:」)で、別の名前でメソッドを追加するためのObjective-Cランタイムを使用しています。このコードでhitTest:withEvent:が呼び出されると、もともとbogusHitTest:withEvent:のコードが実行されます。そのコードを呼び出すとbogusHitTest:withEvent:が呼び出され、元の実装が実行されます。

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

私には分かりませんが、記事は少し古くなっているようです。 Dave DeLongは、はるかに少ないコードでかなりうまく動作するソリューションを発表しました。とにかくありがとう:-) –

+0

@BugAlertちょうどあなたが認識しているので、私のコードは*メソッドswizzlingです。リンクされた記事には、もっと多くの情報があります。 :) –

関連する問題