object-c通知的原理



appTest[64158:fe03] -[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20

2012-06-08 17:09:14.813 appTest[64158:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20'

*** Call stack at first throw:

(

0   CoreFoundation                      0x028bcbe9 __exceptionPreprocess + 185

1   libobjc.A.dylib                     0x02a115c2 objc_exception_throw + 47

2   CoreFoundation                      0x028be6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187

3   CoreFoundation                      0x0282e366 ___forwarding___ + 966

4   CoreFoundation                      0x0282df22 _CF_forwarding_prep_0 + 50

5   Foundation                          0x00d996c1 _nsnote_callback + 145

6   CoreFoundation                      0x02894f99 __CFXNotificationPost_old + 745

7   CoreFoundation                      0x0281433a _CFXNotificationPostNotification + 186

8   Foundation                          0x00d8f266 -[NSNotificationCenter postNotificationName:object:userInfo:] + 134

9   Foundation                          0x00d9b5a9 -[NSNotificationCenter postNotificationName:object:] + 56



2012-06-09 10:14:39.823 appTest[65900:fe03] -[NSCFNumber atestFun:]: unrecognized selector sent to instance 0x6e639a0

2012-06-09 10:14:39.928 appTest[65900:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber atestFun:]: unrecognized selector sent to instance 0x6e639a0'

*** Call stack at first throw:



典型的野指针问题


指针乱指



根据消息的原理,消息必须释放


// remove

[[NSNotificationCenterdefaultCenter]removeObserver:selfname:ANOTIFNAMEobject:nil];


发送消息 call

[[NSNotificationCenterdefaultCenter] postNotificationName:ANOTIFNAME object:theValue];


//add 

[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(atestFun:)name: ANOTIFNAMEobject:nil];

   

通知的原理


通知中心  Menger中根据通知名称创建数组或者树,字典等结构,这里以数组为例来说明

数组中存放对象的指针,当对象进行设置 

[[NSNotificationCenterdefaultCenter] postNotificationName:ANOTIFNAME object:theValue];

的时候添加到对应的数组中


<array name: ANOTIFNAME>

P1

P2

P3

</array>


<array name: ANOTIFNAME2>


</array>


调用的时候,找到对应的数组,对里面的指针(对象)执行其对应的方法,顺序或者多线程执行


如果对象已经释放了,如P1已经是个野指针,call 的时候,进行方法调用,就会出现崩溃


通知必须释放


是一个典型的 观察者模式

 

附:

 

基本简介  观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

编辑本段实现方式

  观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。

编辑本段“观察”不是“直接调用”

  实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。

编辑本段实现观察者模式的过程

  实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。下面的三个图详细的描述了这样一种过程:

1、观察者

  (Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。

2、被观察对象

  被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。

3、撤销观察

  观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。

  观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值