代表人数 iPhoneOS中的通知

mic*_*den 33 iphone notifications delegates

我试图从子视图控制器调用我的根视图控制器中的方法,这样当我更改我的选项时,它们将自动更新根视图,这将更新几个其他视图控制器.对于第二部分,我使用了通知,但为此我首先尝试使用委托,因为它(所以我一直相信)是一个很好的编程习惯.我无法使其工作,并且知道我可以轻松地设置另一个通知来完成这项工作.我应该继续尝试实施代理还是仅使用通知?

Ole*_*ann 59

在许多情况下,委派是一种很好的编程习惯,但这并不意味着如果你不熟悉它就必须使用它.委托和通知都有助于将视图控制器彼此分离,这是一件好事.通知可能更容易编码,并提供多个对象可以观察一个通知的优势.对于代理人来说,如果不修改委托对象就不可能做到这一点(并且很不寻常).

委派的一些好处:

  • 委托对象和委托之间的连接更加清晰,尤其是在强制实施委托时.
  • 如果必须从委托者向委托传递多种类型的消息,则委派可以通过为每个消息指定一个委托方法来使其更清楚. 对于通知,您可以使用多个通知名称,但所有通知最终都以观察者一侧的相同方法结束(可能需要令人讨厌的switch语句).

只有您可以决定哪种模式更适合您.在任何情况下,您都应该考虑不让视图控制器发送通知或委托消息.在许多情况下,视图控制器应该更改模型,然后模型应该通知其观察者或其代理它已被更改.

实现委托模式很简单:

  1. 在ChildViewController.h中,声明委托必须在以后实现的委托协议:

    @protocol ChildViewControllerDelegate <NSObject>
    @optional
    - (void)viewControllerDidChange:(ChildViewController *)controller;
    @end
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在文件的顶部,创建一个实例变量来保存指向ChildViewController中委托的指针:

    @protocol ChildViewControllerDelegate;
    @interface ChildViewController : UIViewController {
        id <ChildViewControllerDelegate> delegate;
        ...
    }
    @property (assign) id <ChildViewControllerDelegate> delegate;
    ...
    @end
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在RootViewController.h中,使您的类符合委托协议:

    @interface RootViewController : UIViewController <ChildViewControllerDelegate> {
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在RootViewController实现中,实现委托方法.此外,在创建ChildViewController实例时,必须分配委托.

    @implement RootViewController
    ...
    // in some method:
    ChildViewController *controller = [[ChildViewController alloc] initWithNibName:...
    controller.delegate = self;
    ...
    - (void)viewControllerDidChange:(ChildViewController *)controller {
        NSLog(@"Delegate method was called.");
    }
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  5. 在ChildViewController实现中,在适当的时候调用委托方法:

    @implementation ChildViewController
    ...
    // in some method:
    if ([self.delegate respondsToSelector:@selector(viewControllerDidChange:)]) {
        [self.delegate viewControllerDidChange:self];
    }
    ...
    
    Run Code Online (Sandbox Code Playgroud)

而已.(注意:我已经从内存中写了这个,所以可能有一些拼写错误/错误.)

  • 你的第二个要点是所有通知都以相同的方法结束,但事实并非如此.通过使用` - [NSNotificationCenter addObserver:selector:name:object:]`,您可以轻松地将不同的通知指向不同的方法. (8认同)

Ben*_*zar 25

我想补充一下:

接收通知的对象只能在事件发生后作出反应.这与授权有显着差异.委托人有机会拒绝或修改委托对象提议的操作.另一方面,观察对象不能直接影响即将发生的操作.


ger*_*ry3 12

通常,如果您需要根据模型中数据的更改来更新UI,您可以让视图控制器观察相关的模型数据,并在收到更改通知时更新其视图.

我认为代表团更正式,就像Peter Hosey最近分享的那样:

不同之处在于委托是针对一个(和双向)通信,而通知是针对多个单向通信的.

此外,我发现(完全)更新视图viewWillAppear:工作正常(但这不是性能受到关注的最佳解决方案).


Ray*_*Fix 6

通知可以使您显著程序的运行时行为更加复杂.认为它喜欢与多个目的地goto语句.这些目的地的顺序没有定义.如果您遇到崩溃,那么堆栈跟踪信息很少.

有些时候是有意义的使用通知 - 典型的一个是通信的模式改变或全局状态改变你的意见.例如,网络出现故障时,应用程序将辞职,等等!

这是值得学习的iOS委托模式.代表们给你完整的堆栈跟踪,当你调试.他们导致显著简单,运行时的行为,同时还实现解耦你的对象的目标.