簡體   English   中英

委托和通知有什么區別?

[英]What is the difference between Delegate and Notification?

委托和通知有什么區別?

我理解為委托和協議,

@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

這也是像委托一樣做幾乎正確的工作。 所以,我什么時候應該使用delgateNSnotification

簡短回答:您可以將代表視為電話。 你打電話給你的朋友,特別想和他們談談。 你可以說些什么,他們可以回應。 你可以一直聊到掛斷電話。 委托以幾乎相同的方式在兩個對象之間創建鏈接,您不需要知道委托的類型,它只需要實現協議。 另一方面,NSNotifications 就像一個廣播電台。 他們向願意傾聽的人廣播他們的信息。 廣播電台無法收到聽眾的反饋(除非它有電話或代表)。 聽眾可以忽略該消息,或者他們可以對其進行處理。 NSNotifications 允許您向任何對象發送消息,但它們之間沒有鏈接來來回通信。 如果您需要這種通信,您可能應該實現一個委托。 否則,NSNotifications 更簡單易用,但可能會給您帶來麻煩。

長答案:

委托通常是一種更合適的處理方式,尤其是在您創建供他人使用的框架時。 當您將協議與委托一起使用時,您將獲得編譯時檢查所需方法的時間,因此您可以在編譯時知道是否缺少任何所需的方法。 使用 NSNotificationCenter 你就沒有這樣的保證。

NSNotificationCenter 是一種“hack-ish”,經常被新手程序員使用,這可能會導致架構不佳。 很多時候這兩個特性是可以互換的,但更多的“鐵桿”開發人員可能會嘲笑 NSNotificationCenter 的使用。


問:使用“id”的原因是什么,它們有什么區別?

A:使用id允許您將任何對象作為參數發送給方法。 請注意,您不能發送諸如 bool、float、double、int 等原語,除非它們被包裝在各自的 Object 包裝器中。


classB{

-(void)DelegateMethod;

}

然后調用它

classA{

   classB delegate;

   -(void)viewdidload{

        [self.delegate DelegateMethod];

    }

}

您提供的上述示例將要求classA的委托始終為classB類型,這並不有利。 在這種情況下不使用委托,您可能只使用引用其他類的變量,例如myClassB 委托的美妙之處在於您可以傳遞任何對象,並且只要它們實現了所需的方法(編譯器可以確保,只要它被標記為正確的委托類型),代碼就可以工作。

委托使用協議並在兩個類之間創建has-a關系。 委托的其他好處之一是您可以將某些東西返回給擁有它的類。

另一方面,通知更適合點對多點通信。 使用NSNotification一個例子可能是在選項卡欄控制器應用程序中,您可能需要將特定事件通知多個視圖控制器,以便它們可以刷新數據等。這對於彼此不了解的類非常有用,並且如果他們這樣做就沒有意義。

現在,對於您的其他問題:

為什么我們使用id
在您的類中,您需要一個不確定類型的對象的句柄,但它實現了您定義的協議。 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

委托將消息從一個對象傳遞到另一個對象。 它就像一對一的通信,而 nsnotification 就像同時將消息傳遞給多個對象。 已訂閱該通知的所有其他對象或該通知的代理觀察者可以或不能響應該事件。 通知更容易,但你可能會因為使用糟糕的架構而陷入困境。 代表更頻繁地使用並且在協議的幫助下使用。

簡單地說,我們可以說,

代表:

一對一

通知:

一對多

聲明委托

@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:完成后。

我們可以出於多種原因使用通知。 例如,您可以廣播通知以根據程序中其他地方的特定事件更改用戶界面元素顯示信息的方式。 或者,您可以使用通知來確保文檔中的對象在文檔窗口關閉之前保存其狀態。

通知的一般目的是將程序事件通知其他對象,以便它們能夠做出適當的響應。但是接收通知的對象只有在事件發生后才能做出反應。 這是與委托的顯着區別。

委托有機會拒絕或修改委托對象提出的操作。 另一方面,觀察對象不能直接影響即將進行的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM