1

ランタイムでUIWebViewのメソッド本体を置き換えることが可能かどうか興味深いですか?UIWebViewをサブクラス化できません

たとえば、次のように実装する必要があります。

- (void) paste:(id)sender;
or
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender;
4

2 に答える 2

4

ランタイムメソッドを試しましたmethod_setImplementationか?

そのようです:

static IMP originalPaste = NULL;

void myPaste(id rcv, SEL cmd, id sender)
{
    // Your implementation here
}

…
{
    …
    Method m = class_getInstanceMethod([UIWebView class], @selector(paste:));
    originalPaste = method_setImplementation(m, myPaste);
    …
}

を使用するoriginalPasteと、実装内でスーパーコールを実行できます。

于 2012-07-06T07:14:38.053 に答える
2

はい、しかし頻繁にそれをしないでください、とアップルは言います:

現在、Objective-C言語では、カテゴリを使用して、クラスが継承するメソッド、またはクラスインターフェイスで宣言されたメソッドをオーバーライドできますが、そうすることは強くお勧めしません。カテゴリはサブクラスの代わりにはなりません。カテゴリを使用してメソッドをオーバーライドすることには、いくつかの重大な欠点があります。

カテゴリが継承されたメソッドをオーバーライドする場合、カテゴリ内のメソッドは、通常どおり、スーパーへのメッセージを介して継承された実装を呼び出すことができます。ただし、カテゴリがそのカテゴリのクラスに存在するメソッドをオーバーライドする場合、元の実装を呼び出す方法はありません。

カテゴリは、同じクラスの別のカテゴリで宣言されたメソッドを確実にオーバーライドすることはできません。

Cocoaクラスの多くはカテゴリを使用して実装されているため、この問題は特に重要です。オーバーライドしようとするフレームワーク定義のメソッド自体がカテゴリに実装されている可能性があるため、どの実装が優先されるかは定義されていません。

一部のカテゴリメソッドが存在すると、すべてのフレームワークで動作が変化する可能性があります。たとえば、NSObjectのカテゴリでwindowWillClose:デリゲートメソッドをオーバーライドすると、プログラム内のすべてのウィンドウデリゲートがcategoryメソッドを使用して応答します。NSWindowのすべてのインスタンスの動作が変わる可能性があります。フレームワーククラスに追加するカテゴリは、動作に不思議な変化を引き起こし、クラッシュにつながる可能性があります。

それ以外は、あなたの人生はサブクラス化せずにかなり難しくなるでしょう。これを実行する(IMPをオーバーライドする)実行時の方法でさえ、「サブクラス化」(クラスペアの割り当て)を伴います。

于 2012-07-05T14:00:44.677 に答える