委任とは何ですか?iOSプログラミングでなぜそれが重要なのですか?


11

現在、私は自分でiOSプログラミングを教えていますが、頭を包み込むのが本当に難しいと思う概念の1つは委任です。それは何ですか?なぜ、どのように使用されていますか?利点は何ですか?私が読んでいる本のテクニカルライティングは、理解するのを難しくしています。


4
スタックオーバーフローの客観的なc + delegatesタグの交差が役立つ場合があります。

回答:


16

理解delegatesするには、理解する必要がありますprotocols

A protocolはサービス契約のようなものです。オブジェクト(ほとんどの場合はUIViewControllerサブクラスですが、常にではありません)がその契約に署名すると、「送信したメッセージをバックアップするロジックを提供することに興味があります」と言っています。これはNSNotificationCenter、関心のあるレベルにサインアップすることと似ていますが、委任を使用するオブジェクトは一度に1つしか持てないという違いがdelegateあり、複数のオブジェクトが同じにサインアップできるためNSNotificationです。

Appleは委任を広く使用しています。しかし、AppleがAPIの多くを他の言語blocksと同様にcallbacksに移行しているのをますます目にしま​​す。

そうは言っても、委任はそれ自体がデザインパターンであると主張しますが、委任はMVCの維持に役立ちます。モデルをコントローラーから分離するのに役立ちます。ジョン・カートライトの例のように、UITableView行とセクションを表示する方法を知っています。UITableViewCellsパフォーマンス上の理由で再利用する方法を知っています。それは他のすべてのものをUIScrollView知っています。しかし、どのセルを表示するかはわかりません。これらのセルにを入力するはわかりません。それは与えられたためにどの細胞を再利用するか知りませんNSIndexPath。とにかく、これは本当にコントローラーの仕事でなければなりません。委任により、テーブルビューは、この非ビューロジックをとにかくその責任を持つオブジェクトにオフロードできます。

それ以上に、オブジェクトの存続期間全体にわたって1つのデリゲートにロックされることはありません。特定のデータソースを複数用意して、UITableView必要に応じて実行時にそれらを切り替えることができます。

そのため、一方で、委任はオブジェクトへのデータの供給とオブジェクトからの対話への応答に最適です。あなたはUIKitのクラスは、そのようなAの多くでそれを参照してくださいよUITableViewUIPickerViewUICollectionView、など

ただし、委任は、オブジェクト間で情報を受け渡したい場合にも非常に便利です。非常に簡単に独自のプロトコルを作成し、独自のオブジェクトにサインアップしてそれらに従うことができます。さらに、プロトコルメソッドは@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つのオブジェクト間の関係は、親/子ほど近くにある必要はありません。これはサービス契約であるため、サインアップするオブジェクトが必要なメソッドを実装することでバーゲンの終わりを保持している限り、あなたは最高です!

注:デリゲートはウィーク/割り当てプロパティである必要があります。そうでない場合は、どちらのオブジェクトも割り当て解除できない保持サイクルに入ります。

お役に立てれば!


2

デリゲートは、通常のオブジェクトに特定の機能を実装する意味がない場合に、特定の機能を実装するオブジェクトです。これは、依存性注入の形式です。

具体的な例については、UITableViewDelegateプロトコルをご覧ください。テーブルビューの行を選択するアクションはアプリごとに、場合によってはテーブルビューごとに異なるため、これらのメソッドはテーブルビューを直接実装する意味がありません。デリゲートにはメソッド-tableView:didSelectRowAtIndexPath:があるため、実装する個々のアクションごとにテーブルビューをサブクラス化せずに行選択を処理するオブジェクトを作成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.