1

プロトコルの一般的な実装でクラスをどのように装飾しますか?

当たり前の質問で申し訳ありません。私は客観的 c に慣れていないので、まだ少し水を踏んでいます。

一般的な実装が必要なプロトコルがあります。

@protocol SelectableElement <NSObject>
@property BOOL selected;
@end

選択可能にしたいオブジェクトがいくつかあります。

@interface Widget : NSObject <SelectableElement>
@end

@interface Duhicky : NSObject <SelectableElement>
@end

私がやりたいことは、プロトコルの実装を一度書き、両方のオブジェクトがそのように実装することを確認することです。

一般的なカテゴリを記述して両方にバインドできるとは思わないので、それを行う1つの方法は、共通クラスNSObjectにカテゴリを実装することだと思います:

@implementation NSObject (Selectable)
- (BOOL)selectable
{
    if (![self conformsToProtocol:@protocol(SelectableElement)]) return;

    return YES; // Use associative storage for this?
}

- (void)setSelectable:(BOOL)selectable
{
    if (![self conformsToProtocol:@protocol(SelectableElement)]) return;

    // set this associatively?
}
@end

もちろん、これを行うためにプロパティ変数を定義することはできません。連想オブジェクト ストアを使用する必要がありますが、ここでは説明しませんでした。

これは、選択可能な要素プロトコルを実装するものに一般的に選択可能な動作を追加する唯一の方法ですか? または、私が見逃しているより明白な方法はありますか?

もちろん、継承を使用してこの単純な例を実装できますが、それはこの方法で単一のプロトコルを実装する場合にのみ機能します。私が提案したこのアプローチは自然にフィットすると考えられますか、それともハックですか?

ジョー

4

3 に答える 3

1

プロトコルを実装するクラスを作成します。SelectableObject次に、WidgetおよびDuhickyクラスが SelectableObject を継承するようにします。

于 2012-05-04T05:31:53.753 に答える
0

Ruby で Mixin のようなものが必要なようですね。残念ながら、これは Objective-C の言語レベルでは不可能です。動作を共有する唯一の方法は、継承によるものです。

そうは言っても、Objective-C ランタイムでいくつかのトリックを実行して、目的を達成することができます。使用している言語に反対するのはおそらく良い考えではありませんが、このオプションを調べたい場合は、http: //cocoadev.com/wiki/MethodSwizzlingをご覧ください。

于 2012-05-08T09:35:05.753 に答える
0

悲しいことに、これは、継承が問題に特に適していないケースの 1 つです。

ただし、Cocoa フレームワーク ( NSResponderまたはUIResponder ) では、この継承の (誤) 使用を確認できます。継承構造 (外部フレームワーク内の一部のオブジェクト) を制御しない場合に、オブジェクトを選択可能にする必要がある場合、問題が発生します。

NSObject のカテゴリは機能しますが、この場合はそれが望ましいと思います。一見すると、すべてのオブジェクトがこれらのメソッドを実行するのは手間がかかるように見えますが、メソッド ルックアップ メカニズムでのキャッシングにより、パフォーマンスの低下はわずかです。

于 2012-05-08T09:57:03.453 に答える