NSNotificationCenter defaultCenter笔记

来源:互联网 发布:网络许可 编辑:程序博客网 时间:2024/05/22 05:12

苹果的消息机制是个非常好用的东西,当需要在类的各个实例之间传递消息或者写一些事件驱动的程序时,绝对是个不错的工具。但是使用时一不小心就会造成引用已经被dealloc的对象的错误,引起程序崩溃。于是,在合适的时机addobserver和removeobserver就是个很关键的事情。下面,分几种情况来阐述一下自己的一点想法。


一,使用defaultcenter。

简单的情况下,若自己没有太多的消息需要注册和处理,直接使用[NSNotificationCenter defaultCenter]来调用默认的消息中心就够用了。如果,有一些特殊的要求那么,就需要试一下一个继承自NSnotificationcenter的子类。

二,在视图显示的时候接受消息。

有些时候,我们需要在一个已经显示在主界面上的ViewController上做一点动作,比如当一个同步过程完成后,把同步的结果显示在界面上。但是,如果这个ViewController没有显示在主界面上的话,它就不关心同步结果是什么样子了。所以这个时候,我们可以在viewwillappear或者viewdidapper中addobserver添加消息监听。然后在viewwilldisappear和viewDidDisappear中removeObserver把消息注销掉。

三,在类的实例存在的时候接受消息。

很多时候,我们需要让一些类的实例只要在内存中,就要接受消息,处理一些事情。比如我们有一个管理同步的类SyncManager,这个类使用了单例模式,从它alloc init之后就需要一些监听同步的状态,并作出处理。这个时候,我们就需要在重写init函数,在其中注册消息。
  1. - (id) init
  2. {
  3.     self = [super init];
  4.     if(self)
  5.     {
  6.          [[NSNotificationCenter defaultCenter] addObserver........]
  7.      }
  8.      return self;
  9. }
复制代码
然后在dealloc中注销
  1. - (void) dealloc

  2.     ......
  3.     [ [NSNotificationCenter defaultCenter] removeObserver.......]
  4.     [super dealloc]
  5. }
复制代码
四,在viewController存在的时候接受消息很多时候,我们会与ViewController打交道,甚至有些时候我们希望只要ViewController在内存中就监听一些消息作出一些动作。刚开始的时候,我想实现这个功能,我是这么写的
  1. - (void) viewDidLoad
  2. {
  3.     ......
  4.     [[NSNotificationCenter defaultCenter] addObserver........]
  5.     .....
  6. }
  7. - (void) viewDidUnload

  8.     ......
  9.     [ [NSNotificationCenter defaultCenter] removeObserver.......]
  10.     ......
  11. }
复制代码
但是,在使用的过程中我发现viewDidLoad和Viewdidunload并不是成对出现的,只有在内存紧张和一些特定的情况下系统才会调用视图的ViewDidUnload来卸载视图。而ViewDIdload每一次加载都会执行。也就是说removeObserver并不一定能够被执行到,这就留下隐患。当视图被dealloc之后,还在监听消息。最终会造成程序的崩溃。而且有些时候如果没有在unload中removeOberver还会造成多次注册同一个消息。造成同一个函数执行多次。引起不必要的麻烦。然后,在使用过程中,经过多次试验我发现,使用init注册消息并在dealloc注销消息最为合适,就像第三条说的那样。在这里值得提醒的一点是苹果的官方文档上说:
  1. The notification center does not retain its observers, therefore, you must ensure that you unregister observers (using removeObserver: or removeObserver:name:object:) before they are deallocated. (If you don't, you will generate a runtime error if the center sends a message to a freed object.)
复制代码

意思是NotificationCenter并不会对Observer进行retain操作。因为就没有必要对observer做多余的release操作,而且,每一次注册,必须对应一次注销,不然,程序死翘翘的事情就会来了。


实际使用过程中,需要非常注意的是:addObserver........和removeObserver.......两个方法要成对出现,在某个地方添加了观察者,就要在某个安全的地方remove掉,不然会造成观察者方法重复调用,即使程序没有崩溃,也会出现很多不确定现象,也不容易发现问题所在。这个是在实际项目中反复调试才发现的,所以记录下来,其实最好还是把苹果的开发文档都通读一遍,这些问题就能避免,但是看文档的时间成本太高,所以发现一个问题,就及时记录下来,避免以后再出类似问题。



转自:http://bbs.9ria.com/thread-226523-1-1.html

原文地址:http://www.1000phone.net/thread-8617-1-1.html
0 0
原创粉丝点击