委托和通知之间有什么区别?

时间:2011-03-16 12:24:45

标签: iphone objective-c cocoa cocoa-touch xcode

委托和通知之间有什么区别?

我理解为代表和协议,

@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 为什么我们不在这样的类A中使用

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。

ThankU

5 个答案:

答案 0 :(得分:106)

简答:您可以将代表视为电话。你打电话给你的好友,特别想与他们交谈。你可以说点什么,他们可以回应。你可以说话,直到你挂断电话。代理以同样的方式在两个对象之间创建链接,并且您不需要知道委托的类型,它只需要实现协议。另一方面,NSNotifications就像一个广播电台。他们向愿意倾听的人传达他们的信息。广播电台无法接收来自听众的反馈(除非有电话或代表)。听众可以忽略该消息,或者他们可以使用它做一些事情。 NSNotifications允许您向任何对象发送消息,但是它们之间不会有来回通信的链接。如果您需要此通信,则应该实现委托。否则,NSNotifications更简单易用,但可能会让您遇到麻烦。

长答案:

代表通常是处理事情的更合适的方式,特别是如果您正在为其他人创建框架以供使用。当您与代理使用协议时,您将获得编译时检查所需的方法,因此如果您缺少任何必需的方法,您就知道何时编译。使用NSNotificationCenter,您没有这样的保证。

NSNotificationCenter 有点“hack-ish”,并且经常被新手程序员使用 导致糟糕的架构。很多时候这两个功能是可以互换的,但更多“硬核”开发人员可能会嘲笑使用NSNotificationCenter。


问: 使用“id”的原因是什么?它们的区别是什么?

A:使用id可以将任何对象作为参数发送到方法。请注意,除非将它们包装在各自的Object包装器中,否则不能发送诸如bools,float,double,int等原语。


classB{

-(void)DelegateMethod;

}

然后在

中调用它
classA{

   classB delegate;

   -(void)viewdidload{

        [self.delegate DelegateMethod];

    }

}

您提供的上述示例要求classA的委托始终属于classB类型,这是不利的。您可能只使用引用其他类的变量,而不是在此方案中使用委托,例如myClassB。委托的优点在于您可以传递任何对象,只要代码实现所需的方法(编译器确保,只要它被标记为正确的委托类型),代码就可以正常工作。

答案 1 :(得分:13)

委托使用协议并在两个类之间创建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

答案 2 :(得分:3)

委托将消息从一个对象传递给另一个对象。它就像一对一的通信,而nsnotification就像是同时将消息传递给多个对象。已订阅该通知的所有其他对象或该通知的代理观察者可以或不可以响应该事件。通知更容易,但您可以通过使用糟糕的架构等方法来解决问题。代表更常使用,并在协议的帮助下使用。

答案 3 :(得分:0)

我们可以出于各种原因使用通知。 例如,您可以广播通知,以更改用户界面元素如何根据程序中其他位置的某个事件显示信息。或者,您可以使用通知来确保文档中的对象在文档窗口关闭之前保存其状态。

通知的一般目的是通知其他对象程序事件,以便它们可以正确响应。但接收通知的对象只能在事件发生后作出反应。这与授权有显着差异。

委托有机会拒绝或修改委托对象提议的操作。另一方面,观察对象不能直接影响即将发生的操作。

答案 4 :(得分:0)

简单地说,我们可以说,

  

代表:

     
    

一对一

  
     

通知:

     
    

一对多

  

宣布代表

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

并声明Protocol

的属性
@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: