21

デリゲートとプロトコルの概念について本当に混乱しています。それらはJavaのインターフェースとアダプタークラスに相当しますか? それらはどのように機能しますか?これまでに読んだリソースはどれも役に立ちませんでした。「委任は、プログラム内の 1 つのオブジェクトが別のオブジェクトに代わって、または他のオブジェクトと連携して動作する単純で強力なパターンです。委任するオブジェクトは、他のオブジェクト (委任) への参照を保持し、適切なタイミングでメッセージを送信します。それに。」これが何を意味するのかわかりません。誰かがそれらが何であるかを説明し、簡単な例を挙げてもらえますか? 前もって感謝します!

編集:

私が今理解している限りでは、

1) デリゲートはプロトコルを実装します (インターフェースの別名)

2) オブジェクトは (プロトコルを実装する) デリゲートを登録します

3) オブジェクトはデリゲートのプロトコル メソッドを呼び出すことができます

したがって、デリゲートはオブジェクトをプロトコルに接続しています。

私が間違っている場合は、私を修正してください。

オブジェクト自体がプロトコルを実装できない理由はまだわかりません。それはずっと簡単だったかもしれません!

4

3 に答える 3

10

で宣言されたプロトコル(@protocol syntax in Objective-C)は、「採用する」(このプロトコルを使用することを宣言する) クラスが実装する一連のメソッドを宣言するために使用されます。これは、「特定のプロトコルを実装している限り、どのクラスを使用してもかまわない」ということをコードで指定できることを意味します。これは、Objective-C で次のように実行できます。

id<MyProtocol> instanceOfClassThatImplementsMyProtocol;

これをコードに記述すると、プロトコル MyProtocol に「準拠」する任意のクラスを変数で使用できますinstanceOfClassThatImplementsMyProtocol。これは、この変数を使用するコードは、クラスに関係なく、この特定の変数で MyProtocol で定義されているメソッドを使用できることを認識していることを意味します。これは、継承設計パターンを回避する優れた方法であり、密結合を回避します。

デリゲートは、プロトコルの言語機能を使用したものです。委任設計パターンは、必要に応じてプロトコルを使用するようにコードを設計する方法です。Cocoa フレームワークでは、デリゲート デザイン パターンを使用して、特定のプロトコルに準拠するクラスのインスタンスを指定します。この特定のプロトコルは、特定のイベントで特定のアクションを実行するためにデリゲート クラスが実装する必要があるメソッドを指定します。デリゲートを使用するクラスは、そのデリゲートがプロトコルに準拠していることを認識しているため、実装されたメソッドを特定の時間に呼び出すことができることを認識しています。この設計パターンは、クラスを分離する優れた方法です。これにより、1 つのデリゲート インスタンスを別のデリゲート インスタンスに簡単に交換できるためです。

プロトコルとデリゲートは、Objective-C と Mac/iOS の開発だけに限定されているわけではありませんが、Objective-C 言語と Apple フレームワークは、この素晴らしい言語機能とデザイン パターンを多用しています。

編集:

この例を見つけてください。UIKit frameworkCocoa Touch にはプロトコルUITextFieldDelegateがあります。UITextFieldこのプロトコルは、インスタンスのデリゲートであるクラスが実装する必要がある一連のメソッドを定義します。つまり、UITextField(delegate プロパティを使用して) にデリゲートを割り当てる場合は、このクラスが に準拠していることを確認する必要がありますUITextFieldDelegate。実際、のデリゲート プロパティUITextFieldは次のように定義されているためです。

@property(nonatomic, assign) id<UITextFieldDelegate> delegate

次に、プロトコルを実装していないクラスをそれに割り当てると、コンパイラは警告を発します。これは本当に便利です。クラスがプロトコルを実装していることを述べる必要があります。そうするということは、他のクラスに、自分のクラスと特定の方法で対話できることを知らせることです。したがって、MyTextFieldDelegateClassのデリゲート プロパティに のインスタンスを割り当てると、 はUITextField、 のUITextField特定のメソッド (テキスト入力、選択などに関連) を呼び出すことができることを認識しますMyTextFieldDelegateClass。プロトコルMyTextFieldDelegateClassを実装すると言っているので、これを知っています。UITextFieldDelegate

最終的に、これらすべてがプロジェクトのコードの柔軟性と適応性を大幅に向上させます。このテクノロジを使用した後、すぐにそれを実現できると確信しています! :)

于 2013-06-19T13:27:32.980 に答える
9

最も単純な形式では、デリゲートは別のオブジェクトからメッセージを受け取るオブジェクトです。そして、あなたはいつもそれをします。

たとえば、エンジン付きの車のオブジェクトがあるとします。

@interface car : NSObject

@property (nonatomic) id engine;

@end

そのため、エンジンに開始メッセージを転送できます。

[_engine start];

エンジンはデリゲートとして機能しており、メッセージを渡すだけです。

プロトコルはそれをより正式なものにし、Xcode は必須またはオプションのメソッドに準拠しているかどうかをチェックします。

@property (nonatomic) id <engineDelegate> engine;

は、プロトコル定義でそれを要求したため、エンジン オブジェクトに関数 start を含める必要があると述べています。

@protocol engineDelegate 
 - (void) start;
@optional
 - (double) fuelLevel;
@end

デリゲートとプロトコルはなぜクールなのか? エンジンは、実行時に使用できる任意の数の異なるエンジンである可能性があるため、プロトコルに準拠している限り、ジェット エンジン、燃焼エンジン、位相変調エンジンなどは問題ではありません。そして、デリゲートをクラス インターフェイスに追加することで、準拠していることを Xcode に伝えます。

@interface timeWarpDrive : NSObject <engineDelegate>
于 2014-05-28T03:37:14.927 に答える