2012-04-27 27 views
3

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

+1

サブクラス化してそのプロトコルを追加してみませんか? – kuba

+1

@kuba、それは私が自分自身をインスタンス化するインスタンスだけでなく、フレームワークによって提供される既存のインスタンスに追加したいからです。 – SoftMemes

答えて

8

あなたのような何かをしたいので、あなたは、プロトコルに準拠したカテゴリを定義することができます。

@interface UIWebView (MyGreatExtensions) <UITableViewDelegate> 
@end 

@implementation UIWebView (MyGreatExtensions) 

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

// ... 

@end 

を検討するために小さなエッジケースは、(他のもし誰かが同じことをしようとするということですサードパーティ製のフレームワークもカテゴリを介してプロトコルを追加します)バージョンが使用されることは保証できません。

このアプローチに関する詳細from Mark Dalrymple

+0

私はプロトコル自体と実装の両方を所有しているので、最後の懸念事項は実際にはこの場合問題ではありません。 UITableViewDelegateの場合、これにより、UIWebViewの既存のインスタンスがconformsToProtocolでtrueになるのでしょうか? – SoftMemes

+0

はい、そうです。実際には「既存のインスタンス」はありません。プロトコルの実装を追加することでクラスを拡張しています。 –

+0

優秀、ありがとう! – SoftMemes

1

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

また、あなたのオブジェクトは、プロトコルを実装しないことに同意することにランタイムチェックを欺くために、あなたはNSObjectののクラスメソッドconformsToProtocolをオーバーライドすることもできますので、のように:

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

あなたがオーバーライドする必要が複数のメソッドがあるかもしれません1つの例は、NSObjectのinstancesRespondToSelector:とresolve *:メソッドです。詳細については、NSObject class referenceを調べてください。

関連する問題