web-dev-qa-db-ja.com

代理人と通知の違いは何ですか?

代理人と通知の違いは何ですか?

私はデリゲートとプロトコルのように理解しました、

@protocol classADelegate

-(void)DelegateMethod;


@end



classB <classADelegate>{

   classA *ObjOfclassA=[[classA alloc]init];

    ObjOfclassA.delegate=self;

//while Push later, here we have taken the pointer of classB(self) to classA and stored in delegate variable of classA. so from classA we can call the function in classB

   Push:classA from here.


   -(void)DelegateMethod{

        nslog(@"i am rithik from India");


     }

}


classA{

   id <classADelegate> delegate;

   -(void)viewdidload{

        [self.delegate DelegateMethod];

    }

}

私の疑いは

1このようにclassAで使用しない理由

classA{

**classB** <classADelegate> delegate;


[self.delegate DelegateMethod];

}

"id"を使用する理由は何ですか?それらの違いは何ですか?

2プロトコル定義に由来するclassBのDelegateMethod関数のメソッドを呼び出します。

代わりに、classBのインスタンスメソッドを定義することで、そのメソッドを直接呼び出すことができます。これは、classAのデリゲート変数にclassBのポインタがあるためです。

このような。

classB{

-(void)DelegateMethod;

}

そしてこれを

classA{

       classB delegate;

       -(void)viewdidload{

            [self.delegate DelegateMethod];

        }

    }

したがって、上記からプロトコルとID変数を回避しました

しかし、私は多くの人がデリゲートとプロトコルを使用していることを知っていました。ここで私はデリゲートとプロトコルを使用しているときに利点について知った

ここで、DelegateMethod関数のメソッドのプロトコル実装の使用法は何ですか。

代わりにインスタンス定義。

@protocolによるそれらの使用法は何ですか。

誰かが私を正しい方向に導いてください...

私はiphoneの開発に不慣れです。

今、私はデリゲートを作成する方法を知っていましたが、NSNotificationについて勉強するようになりました

それは、デリゲートのようなほぼ正しい仕事もします。

したがって、いつdelgateまたはNSnotificationを使用する必要がありますか。

Thank

19
rithik

短い回答:デリゲートは電話のようなものと考えることができます。あなたはあなたの仲間を呼び、特に彼らと話したいです。あなたは何かを言うことができ、彼らは応答することができます。電話を切るまで話すことができます。デリゲートは、ほぼ同じ方法で2つのオブジェクト間にリンクを作成します。デリゲートのタイプを知る必要はなく、プロトコルを実装するだけです。一方、NSNotificationsはラジオ局のようなものです。彼らは聞いてくれる人にメッセージを放送します。ラジオ局は、そのリスナーからのフィードバックを受信できません(電話または代理人がいない場合)。リスナーはメッセージを無視することも、メッセージを使って何かをすることもできます。 NSNotificationsを使用すると、任意のオブジェクトにメッセージを送信できますが、相互に通信するためのオブジェクト間のリンクはありません。この通信が必要な場合は、おそらくデリゲートを実装する必要があります。それ以外の場合は、NSNotificationsの方が簡単で使いやすいですが、問題が発生する可能性があります。

長い回答:

特に他の人が使用するフレームワークを作成している場合は、通常、デリゲートがより適切な処理方法です。デリゲートでプロトコルを使用すると、必要なメソッドのコンパイル時間を確認できるため、必要なメソッドがない場合にコンパイルするときにわかります。 NSNotificationCenterでは、そのような保証はありません。

NSNotificationCenterはkind of "hack-ish"であり、canアーキテクチャの貧弱化につながる初心者プログラマーとして頻繁に使用されています。多くの場合、これら2つの機能は互換性がありますが、より多くの「ハードコア」開発者がNSNotificationCenterの使用を嘲笑する可能性があります。


Q:「id」を使用する理由とその違いは何ですか?

A:idを使用すると、任意のオブジェクトをパラメーターとしてメソッドに送信できます。 bool、float、double、intなどのプリミティブは、それぞれのObjectラッパーでラップしない限り送信できないことに注意してください。


classB{

-(void)DelegateMethod;

}

そしてこれを

classA{

   classB delegate;

   -(void)viewdidload{

        [self.delegate DelegateMethod];

    }

}

上記の例では、classAのデリゲートは常にタイプclassBである必要がありますが、これは有利ではありません。このシナリオでデリゲートを使用する代わりに、他のクラスを参照する変数、たとえばmyClassBを使用することになるでしょう。デリゲートの利点は、任意のオブジェクトを渡すことができることです。コードは、必要なメソッドを実装している限り機能します(正しいデリゲートタイプとしてマークされている限り、コンパイラーはこれを保証します)。

107
FreeAsInBeer

デリゲートはプロトコルを使用して、2つのクラス間にhas-a関係を作成します。デリゲートのその他の利点の1つは、所有しているクラスに何かを戻すことができることです。

一方、通知は、ポイントツーマルチポイント通信を対象としています。 NSNotificationの使用例は、タブバーコントローラーアプリケーションである場合があります。このアプリケーションでは、データを更新できるように、特定のイベントを複数のビューコントローラーに通知する必要があります。これは知識のないクラスに最適です。お互いがそうであったとしても、意味がありません。

さて、あなたの他の質問に:

なぜidを使用するのですか?
あなたのクラスでは、不定typeのオブジェクトへのハンドルが必要ですが、これは定義したプロトコルを実装します。 UIWebViewを例にとってみましょう。デリゲートになり得るクラスの種類はごくわずかである可能性があるため、特定の種類のクラスに名前を付けるのではなく、クラスがUIWebViewDelegateプロトコルを実装する必要があることを指定する必要があります。これにより、結合が最小限に抑えられ、状態ではなく動作に基づいてインタラクションを作成する非常にまとまりのあるアプリケーションが作成されます。

それでは、例を見てみましょう。

@protocol ClassADelegate
- (NSString*) determineValue;
@end

@interface ClassA : NSObject
{
    id<ClassADelegate> delegate;
}
//  Make sure you are using assign, not retain or copy
@property (nonatomic, assign) id<ClassADelegate> delegate;

@end

ClassAの実装:

import "ClassA.h"

@implementation ClassA
@synthesize delegate;

- (void) somePrivateMethod
{
    if (self.delegate && [self.delegate implementsProtocol:@protocol(ClassADelegate)])
    {
        NSString* value = [self.delegate determineValue];

        // Do other work
    }
}

- (void) dealloc
{
    delegate = nil;
}

@end

ヘッダーで、クラスがClassADelegateプロトコルを実装することを宣言します。

#import "ClassA.h"

@interface ClassB : NSObject <ClassADelegate>
{
}

- (void) someMethod;

@end

ClassBの実装では、ClassAのインスタンスを作成し、BをAのデリゲートとして設定します。

#import "ClassB.h"
@implementation ClassB

- (void) someMethod
{
    ClassA* aClass = [[ClassA alloc] init];

    aClass.delegate = self;

   // Other work and memory clean up of A.
   // Some logic occurs in A where it calls the delegate (self) which will 
   // call the `determineValue` method of this class.
}

//  Here's the delegate method we implement
- (NSString*) determineValue
{
    return @"I did some work!";
}

@end
14
Wayne Hartman

デリゲートは、あるオブジェクトから別のオブジェクトにメッセージを渡します。 nsnotificationは複数のオブジェクトに同時にメッセージを渡すようなものですが、これは1対1の通信のようなものです。その通知をサブスクライブしている他のすべてのオブジェクト、またはその通知の代理オブザーバーは、そのイベントに応答できる場合と応答できない場合があります。通知はより簡単ですが、悪いアーキテクチャのようなものを使用することでトラブルに陥ることがあります。デリゲートはより頻繁に使用され、プロトコルの助けを借りて使用されます。

3
Aman Pathak

通知はさまざまな理由で使用できます。 、プログラムの他の場所にある特定のイベントに基づいて、ユーザーインターフェイス要素が情報を表示する方法を変更する通知をブロードキャストできます。または、ドキュメントウィンドウを閉じる前に、ドキュメント内のオブジェクトの状態を確実に保存する方法として通知を使用することもできます。

通知の一般的な目的は、プログラムイベントを他のオブジェクトに通知して、適切に応答できるようにすることです。ただし、通知を受信するオブジェクトは、イベントが発生した後にのみ反応できます。これは委任との大きな違いです。

デリゲートには、デリゲートオブジェクトによって提案された操作を拒否または変更する機会が与えられます。一方、オブジェクトを観察することは、差し迫った操作に直接影響を与えることはできません。

0

簡単に言うと、

代議員:

1対1

お知らせ:

1から-多く

委任を宣言するには

@protocol DelegateName
@required
- (void)method:(NSString *)param;
@optional
- (void)methodOptional:(NSString *)param;
@end

そして、プロトコルのプロパティを宣言します

@property id <DelegateName> delegate;

使用できます

myObject.delegate = <# some object conforming to DelegateName #>;

NSNotification宣言

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(notificationHappened:)
                                             name:MyCustomNotificationName
                                           object:nil];

次に実装

- (void)notificationHappened:(NSNotification *)notification {
    // do work here
}

通知はどこからでも投稿できます。

[[NSNotificationCenter defaultCenter] postNotificationName:MyCustomNotificationName
                                                    object:self
                                                  userInfo:nil];

終了したら、removeObserver:に電話してください。

0
Lal Krishna