3

カテゴリを使用してクラス(フレームワーククラスなど)を拡張できることは知っていますが、ソースコードを制御していないクラスにカスタムプロトコルの1つを実装させることは可能ですか?インスタンスに送信された場合に特定のメッセージに応答するようにするだけでなく、理想的には、そのクラスのオブジェクトが、プロトコルを照会するときに実行時型チェックでtrueを返すようにします。

4

2 に答える 2

8

プロトコルに準拠するカテゴリを定義できるので、次のようにします。

@interface UIWebView (MyGreatExtensions) <UITableViewDelegate>
@end

@implementation UIWebView (MyGreatExtensions)

- (CGFloat)tableView: (UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath {
  return 42.0;
}

// ...

@end

考慮すべき小さなエッジケースは、他の誰かが同じことをしようとした場合(たとえば、サードパーティのフレームワークもカテゴリを介してプロトコルを追加する場合)バージョンが使用されることを保証できないことです(もちろん、どちらも使用できません)彼ら)。

MarkDalrympleによるこのアプローチの詳細。

于 2012-04-27T09:01:16.857 に答える
2

これは可能だと思います。NSObjectのforwardInvocation:メソッドを上書きし、プロトコルの実装者が応答するすべての認識されないメッセージをインターセプトすることで、Objective-Cで動的プロキシを簡単に作成できます(これがNSUndoManagerの魔法です)。私はこれを自分でやったことがないので、これを行うためのよりエレガントな方法があるかもしれません。

さらに、ランタイムチェックをだまして、オブジェクトがプロトコルを実装していることに同意させるために、NSObjectのクラスメソッドconformsToProtocolをオーバーライドできます。

+ (BOOL)conformsToProtocol:(Protocol *)aProtocol {
    if (aProtocol == @protocol(MyDynamicallyImplementedProtocol))
        return YES;
    return [super conformsToProtocol:aProtocol];
}

オーバーライドする必要のあるメソッドが他にもある可能性があります。たとえば、NSObjectのinstancesRespondToSelector:メソッドとresolve *:メソッドがあります。詳細については、NSObjectクラス参照を調べてください。

于 2012-04-27T08:54:33.310 に答える