現在、私は自分でiOSプログラミングを教えていますが、頭を包み込むのが本当に難しいと思う概念の1つは委任です。それは何ですか?なぜ、どのように使用されていますか?利点は何ですか?私が読んでいる本のテクニカルライティングは、理解するのを難しくしています。
現在、私は自分でiOSプログラミングを教えていますが、頭を包み込むのが本当に難しいと思う概念の1つは委任です。それは何ですか?なぜ、どのように使用されていますか?利点は何ですか?私が読んでいる本のテクニカルライティングは、理解するのを難しくしています。
回答:
理解delegates
するには、理解する必要がありますprotocols
。
A protocol
はサービス契約のようなものです。オブジェクト(ほとんどの場合はUIViewController
サブクラスですが、常にではありません)がその契約に署名すると、「送信したメッセージをバックアップするロジックを提供することに興味があります」と言っています。これはNSNotificationCenter
、関心のあるレベルにサインアップすることと似ていますが、委任を使用するオブジェクトは一度に1つしか持てないという違いがdelegate
あり、複数のオブジェクトが同じにサインアップできるためNSNotification
です。
Appleは委任を広く使用しています。しかし、AppleがAPIの多くを他の言語blocks
と同様にcallbacks
に移行しているのをますます目にします。
そうは言っても、委任はそれ自体がデザインパターンであると主張しますが、委任はMVCの維持に役立ちます。モデルをコントローラーから分離するのに役立ちます。ジョン・カートライトの例のように、UITableView
行とセクションを表示する方法を知っています。UITableViewCells
パフォーマンス上の理由で再利用する方法を知っています。それは他のすべてのものをUIScrollView
知っています。しかし、どのセルを表示するかはわかりません。これらのセルに何を入力するかはわかりません。それは与えられたためにどの細胞を再利用するか知りませんNSIndexPath
。とにかく、これは本当にコントローラーの仕事でなければなりません。委任により、テーブルビューは、この非ビューロジックをとにかくその責任を持つオブジェクトにオフロードできます。
それ以上に、オブジェクトの存続期間全体にわたって1つのデリゲートにロックされることはありません。特定のデータソースを複数用意して、UITableView
必要に応じて実行時にそれらを切り替えることができます。
そのため、一方で、委任はオブジェクトへのデータの供給とオブジェクトからの対話への応答に最適です。あなたはUIKitのクラスは、そのようなAの多くでそれを参照してくださいよUITableView
、UIPickerView
、UICollectionView
、など
ただし、委任は、オブジェクト間で情報を受け渡したい場合にも非常に便利です。非常に簡単に独自のプロトコルを作成し、独自のオブジェクトにサインアップしてそれらに従うことができます。さらに、プロトコルメソッドは@required
デフォルトではありますが、いくつかのメソッドを指定して、@optional
。これにより、必要に応じて柔軟性が向上します。親のView Controllerと子のView Controllerがあるとします。たぶん、あなたはこれを行うために新しいContainment APIを使用しています。通常、親から子に情報を渡す必要がある場合は、プロパティを使用してこれを行います。できた しかし、子から親に情報を渡す必要がある場合はどうでしょうか?たぶん、子で何かが変わったので、親に通知する必要があります。もちろん、特定の値に対してKVOを実行できます。しかし、ボタンが押されたときを知りたいかもしれません。子View Controllerで新しいプロトコルを作成するだけです
@protocol MyChildDelegate
- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController;
@end
@interface MyChildViewController : UIViewController
@property (weak, nonatomic) id <MyChildDelegate> delegate;
@end
MyChildViewControllerで、ボタンがタップされたら、デリゲートがデリゲートメッセージに応答するかどうかを確認します(必要であり、デリゲートがメソッドを実装しない場合、クラッシュします。@optional
必要であればメソッドを作成できます)。それ:
- (IBAction)someButtonTapped:(id)sender {
if ([self.delegate respondsToSelector:@selector(buttonWasTappedInChild:)]) {
[self.delegate buttonWasTappedInChild:self];
}
}
次に、MyChildViewControllerのデリゲートを設定して、親View Controllerにself
実装- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
します。ブーム!子から親に渡される情報があります。2つのオブジェクト間の関係は、親/子ほど近くにある必要はありません。これはサービス契約であるため、サインアップするオブジェクトが必要なメソッドを実装することでバーゲンの終わりを保持している限り、あなたは最高です!
注:デリゲートはウィーク/割り当てプロパティである必要があります。そうでない場合は、どちらのオブジェクトも割り当て解除できない保持サイクルに入ります。
お役に立てれば!
デリゲートは、通常のオブジェクトに特定の機能を実装する意味がない場合に、特定の機能を実装するオブジェクトです。これは、依存性注入の形式です。
具体的な例については、UITableViewDelegateプロトコルをご覧ください。テーブルビューの行を選択するアクションはアプリごとに、場合によってはテーブルビューごとに異なるため、これらのメソッドはテーブルビューを直接実装する意味がありません。デリゲートにはメソッド-tableView:didSelectRowAtIndexPath:
があるため、実装する個々のアクションごとにテーブルビューをサブクラス化せずに行選択を処理するオブジェクトを作成できます。