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

一,使用defaultcenter。

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

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

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

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

很多时候,我们需要让一些类的实例只要在内存中,就要接受消息,处理一些事情。比如我们有一个管理同步的类SyncManager,这个类使用了单例模式,从它alloc init之后就需要一些监听同步的状态,并作出处理。这个时候,我们就需要在重写init函数,在其中注册消息。

- (id) init
{
self = [super init];
if(self)
{
[[NSNotificationCenter defaultCenter] addObserver........]
}
return self;
}

然后在dealloc中注销

- (void) dealloc
{
......
[ [NSNotificationCenter defaultCenter] removeObserver.......]
[super dealloc]
}

四,在viewController存在的时候接受消息

很多时候,我们会与ViewController打交道,甚至有些时候我们希望只要ViewController在内存中就监听一些消息作出一些动作。刚开始的时候,我想实现这个功能,我是这么写的

- (void) viewDidLoad
{
......
[[NSNotificationCenter defaultCenter] addObserver........]
.....
}
- (void) viewDidUnload
{
......
[ [NSNotificationCenter defaultCenter] removeObserver.......]
......
}

但是,在使用的过程中我发现viewDidLoad和Viewdidunload并不是成对出现的,只有在内存紧张和一些特定的情况下系统才会调用视图的ViewDidUnload来卸载视图。而ViewDIdload每一次加载都会执行。

也就是说removeObserver并不一定能够被执行到,这就留下隐患。当视图被dealloc之后,还在监听消息。最终会造成程序的崩溃。而且有些时候如果没有在unload中removeOberver还会造成多次注册同一个消息。造成同一个函数执行多次。引起不必要的麻烦。

然后,在使用过程中,经过多次试验我发现,使用init注册消息并在dealloc注销消息最为合适,就像第三条说的那样。在这里值得提醒的一点是苹果的官方文档上说:

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操作,而且,每一次注册,必须对应一次注销,不然,程序死翘翘的事情就会来了。

转:http://www.cnblogs.com/yishuiliunian/archive/2012/04/03/2431506.html

NSNotificationCenter消息注册与撤销的更多相关文章

  1. IOS学习之NSNotificationCenter消息机制

    NSNotificationCenter是 Cococa消息中心,统一管理单进程内不同线程的消息通迅. 添加观察者接收通知: //添加通知中心观察者 [[NSNotificationCenter de ...

  2. NSNotificationCenter消息机制的介绍

    转载自http://www.cnblogs.com/pengyingh/articles/2367374.html NSNotificationCenter的作用是专门提供程序中不同类之间的消息通讯而 ...

  3. NSNotificationCenter消息通信机制

    作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的. 注册通知:即要在什么地方接受消息 [[NSNotificationCenter defaultCenter] ...

  4. NSNotificationCenter消息通信(KVO)

    NSNotificationCenter是程序不同类间的消息通信. 注册消息通知: [[NSNotificationCenter defaultCenter]addObserver:self sele ...

  5. 关于NSNotificationCenter消息通信用法

    NSNotificationCenter主要用于广播消息到多个监听着,其传统用法 - (void)viewDidLoad { [super viewDidLoad]; [[NSNotification ...

  6. iOS设计模式之NSNotificationCenter 消息中心

    消息中心模式和KVO模式有点相似,差别在于.KVO  模式是意图在于监听摸一个相应的值的变化.而去出发一个方法相应的动作.而消息中心在于,广播.它就像一个广播基站,发送一条消息,在全部的加入监听的地方 ...

  7. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  8. MVVM模式用依赖注入的方式配置ViewModel并注册消息

    最初的想法 这次主要讨论下给View指定ViewModel的事情.一般来说给View指定ViewModel常用的方式有两种,一种是在View的后台代码中写DataContext = new ViewM ...

  9. Posix消息队列

    转载于:http://blog.csdn.net/zx714311728/article/details/53197196 1.消息队列 消息队列可以认为是一个消息链表,消息队列是随内核持续的.队列中 ...

随机推荐

  1. nginx:支持跨域访问

    在http节点中配置: #支持跨域访问 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Header ...

  2. 解决UnicodeDecodeError: 'ascii' codec can't decode byte 0xcf in position 7: ordinal not in range(128)

    在Windows下同时装了Python2和Python3,但是在使用命令给pip更新的时候,出现了以下错误: 解决办法:修改mimetypes.py文件,路径位于python的安装路径下的Lib\mi ...

  3. ThinkPHP中的统计查询方法

    • count() 表示查询表中总的记录数 • max() 表示查询某个字段的最大值 • min() 表示查询某个字段的最小值 • avg() 表示查询某个字段的平均值 • sum() 表示求出某个字 ...

  4. oracle创建表空间并赋予权限

    CREATE TEMPORARY TABLESPACE 表空间 TEMPFILE  数据存储路径('D://oracle//NEW_NAMESPACE.DBF') SIZE 32M AUTOEXTEN ...

  5. java 标准异常

    一.Throwable这个Java类被用来表示任何可以作为异常被抛出的类.Throwable对象可分为两种类型(从Throwable继承而得到的类型): 1.) Error用来表示编译时和系统错误 2 ...

  6. hdu 1166 线段树(单点增减 区间求和)

    Sample Input1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10End Sample Outp ...

  7. Android开源库集合(工具)

    图片加载框架: Glide https://github.com/bumptech/glide Android-Universal-Image-Loader https://github.com/no ...

  8. Redux架构

    深入Redux架构   阅读目录 关于redux API 中间件与异步操作 异步操作的基本思路 React-Redux的用法 回到顶部 关于redux 之前写了一篇通过一个demo了解Redux,但对 ...

  9. 【LOJ】#121. 「离线可过」动态图连通性

    题解 和BZOJ4025挺像的 就是维护边权是时间的最大生成树 删边直接删 两点未联通时直接相连,两点联通则找两点间边权小的一条边删除即可 代码 #include <bits/stdc++.h& ...

  10. Linux性能优化之CPU优化(一)

    前言 何为性能优化?个人认为,性能优化是为了提高应用程序或系统能力为目的.那么如何才能实现对应用程序的性能调优呢?这里很设计到很多的内容,包括Linux内核.CPU架构以及Linux内核对资源的分配以 ...