質問はこれです:
私は、他の2つのコントローラーController 2およびController 3のデリゲートであるビューコントローラーController 1を持っています。
コントローラ 2には「FOO」というデリゲート メソッドがあり、コントローラ 3には同じメソッドがあります。
両方の「FOO」メソッドがデリゲートにまったく同じことを行うように指示する場合、コントローラー 1内に 1 つの「FOO」メソッドを実装できます か?
ありがとう
シャニ
適切なデリゲートの設計とは、メソッドが同じ名前であってはならないことを意味します。たとえば、 と という名前の 2 つのクラスがFooA
ありFooB
、どちらも委譲アクションを実行するfoobar:(BOOL)force
場合、デリゲート メソッド名は次のようになります。
- (void)fooA:(FooA*)foo foobar:(BOOL)force;
- (void)fooB:(FooB*)foo foobar:(BOOL)force;
このようにして、「コントローラー 1」は 2 つのデリゲート メソッドを区別できるようになります。UITableView
たとえば、次のような他のデリゲートでこれに気付くでしょう。
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
あるクラスまたは別のクラスにshouldHighlightRowAtIndexPath
由来するかどうかを区別できます。UITableView
つまり、1 つのメソッド名を 2 つのデリゲート間で共有することは完全に可能です。デリゲートがデリゲートのソースを確認できないだけです。
あなたはこれができますか?はい。これを行う必要がありますか?間違いなくいいえ。各View Controllerがプロトコルを定義していると仮定すると、すべてのプロトコルのメソッドに一意の名前を付ける必要があります。つまり、コントローラー 2のプロトコルとコントローラー 3のプロトコルの両方に、単に名前が付けられたメソッドがある場合、foo
それは間違っています。controller1foo:
とが必要controller2foo:
です。
その理由は次のとおりです。コントローラー 1ではこれらの両方を同じように処理したい場合がありますが、別のコントローラーではそれらを異なる方法で処理する必要がある可能性があります。または、将来、コントローラー 1がそれらを別の方法で処理する必要があると判断するかもしれません。両方のプロトコルが同じメソッドを定義している場合、それらを別々に処理する方法はありません。
これが適切な解決策です。各プロトコル メソッドに一意の名前を付けます。次にController 1で、両方のデリゲート メソッドを実装します。ただし、両方のデリゲート メソッドの実装は、実際の作業を行う共通のメソッドを呼び出すことになります。
コントローラ 1で:
- (void)doTheCommonWork {
// This method does the common processing of the delegate calls
}
#pragma mark Controller 2 methods
- (void)controller2foo:(Controller2 *)controller {
[self doTheCommonWork];
}
#pragma mark Controller 3 methods
- (void)controller3foo:(Controller3 *)controller {
[self doTheCommonWork];
}
このアプローチでは、両方のデリゲート メソッドに対して同じことを行うことができますが、必要に応じて別のことを行うこともできます。
コントローラーはクラスの 2 と 3 のインスタンスですか?
そこで、コントローラー 2 が DoSomethingController であり、コントローラー 3 が DoSomethingElseController であると仮定しましょう。この場合、2 つの異なるデリゲート メソッドが必要になります。
代わりに、コントローラー 2 と 3 が同じクラスである場合、またはコントローラーのクラスの 1 つが他のクラスのサブクラスである場合、これも問題ありません。例:UITableView
のサブクラスはデリゲート メソッドを 1 つのデリゲート オブジェクト (コントローラー 1) とUITableView
共有できますが、これは問題ありません。tableView:cellForRowAtIndexPath: