您的位置:首页 > 其它

通知的具体使用——通知的发送、接受、通知的移除

2015-09-21 21:19 351 查看
1、移除观察者身份
我们可以通过发送一条指定观察方对象和键路径的removeObserver:forKeyPath: 消息至被观察的对象,来移除一个键-值观察者,来移除一个键值观察者。(当我们达到目的后)。
[child removeObserver:self forKeyPath: @“key”];
2、接收变更通知
接受变更通知:
当对象的一个被观察属性发生变动时,观察者收到一个observeValueForKeyPath: ofObject: change: context: 消息。所有观察者都必须实现这一方法。触发观察通知的对象和键路径、包含变更细节的字典,以及观察者注册时的上下文指针均被交给观察者,context可以为任意类型的参数。
但相比而言,通知更广泛一点。
3、通知的使用步骤如下:
(1) 使用通知必须要建立通知对象。通知是一个单例对象,由通知中心创建,具体方法如下:

[NSNotificationCenterdefaultCenter]
(2)注册通知。

- (void)addObserver:(id)observer selector:(SEL)aSelector
name:(NSString *)aName object:(NSString *)anObject;

此方法是用来为对象注册监听事件的。 所谓的注册监听事件就是指接受到指定的通知时触发某方法事件。参数解析如下:
observer: 指为哪个对象添加接受通知后的触发事件,即被触发后的事件方法在哪个类中实现,observer就指向哪个类的对象。
selector: 触发事件接口。赋值为@selector(触发事件方法名:) 意思就是接受指定的通知后执行observer对象的此方法
name:指通知的名称。即为对象注册监听事件时必须指明接受的是什么通知,对通知进行了过滤。当名称为name的通知才会被接受然后触发监听事件。
object可以赋值为nil
注意: 触发事件的方法名一般都带有NSNotification对象参数,这样当别的地方发送带有对象的相应通知时便会由addObserver接受通知并把发送的对象存在NSNotification对象参数的Object变量中,这样一来就可以直接在触发事件中操纵处理通知发送过来的对象。
(3)发送通知。
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
aName: 即表示发送名称为aName的通知,与接受通知的部分即注册通知部分的aName是对应的。
object:表示在发送通知的同时还要传递一个对象 一般把自己发送出去。由addObserver接受通知,并将对象传给触发事件的NSNotification参数。
(4)最后移除通知

- (void)removeObserver:(id)observer;
observer: 需要移除通知监听的对象
在一个对象中可以注册多个监听事件,每个监听都可以接受不同的对应通知,并触发不同的事件。 当所有操作完毕后不必再一一进行移除通知,只需要让已经添加通知的对象调用此方法便可以移除所有的监听通知。
- (void)removeObserver:(id)observer name:(NSString *)aName
object:(id)anObject;
如果在特定情况下不想全部移除通知,只想移除特定通知的话,调用此方法即可
新建工程代码如下:
child.h

<span style="font-size:18px;">//
//  Child.h
//  KVOTest
//
//  Created by yanlu guo on 13-7-28.
//  Copyright (c) 2013年 河北科技大学. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Child : NSObject
@property(nonatomic,assign) NSInteger happyVal;

@end
</span>
child.m

<span style="font-size:18px;">//
//  Child.m
//  KVOTest
//
//  Created by yanlu guo on 13-7-28.
//  Copyright (c) 2013年 河北科技大学. All rights reserved.
//

#import "Child.h"

@implementation Child

// 可以发现孩子类中并没有护士的对象  但是护士仍然受到了通知
// 并不只是护士 ,而是所有的类的中都可以为孩子添加一个观察者
-(id)init{
if(self = [super init]){
self.happyVal = 100;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
}
return self;

}

-(void) timerAction:(NSTimer *) timer{
_happyVal--;
NSLog(@"_happyValue=  %ld",_happyVal);
if (_happyVal <80) {
//        NSNumber *happ = [NSNumber numberWithInteger:_happyVal];  // 将基本数据包装成NSNumber类型

// 开始发送通知   postNotificationName: 相当于暗号和必须和接受通知的暗号相一致
/* object: 发送一个参数,必须是对象类型。所以若是基本值的话要用NSNumber进行包装
但一般为了控制修改该对象的属性,就把当前对象传过去,方便在通知触发的监听方法体内
修改此对象的属性值
*/
[[NSNotificationCenter defaultCenter] postNotificationName:@"happyValChange" object:self];
}
}
@end
</span>
Nurse.m

<span style="font-size:18px;">//
//  Nurse.m
//  KVOTest
//
//  Created by yanlu guo on 13-7-28.
//  Copyright (c) 2013年 河北科技大学. All rights reserved.
//

#import "Nurse.h"
#import "Child.h"

@implementation Nurse
-(id) init
{
if(self = [super init]){

// 监听一个通知,通知名为@"happyValChange"  当接收到通知时调用notificationAction方法
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction:) name:@"happyValChange" object:nil];
/*
NSNotificationCenter:  通知中心   defaultCenter:表示创建的通知中心对象是一个单例  name: 表示通知的名称,是由我们自己定义的
*/
}
return self;
}

-(void)notificationAction:(NSNotification *) notification
{
Child *chil = notification.object;
[self play:chil];
}

-(void)play:(Child *) chile
{
NSLog(@"保姆逗小孩玩");
chile.happyVal = 100;
}

-(void)dealloc
{
//    // 移除指定通知名为@"happyValChange" 的通知
//    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValChange" object:nil];

// 移除当前对象上所有的通知
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@end

/*
通知与KVO的区别:
KVO的通知是由系统发送的。
而NSNOtification 是由我们自己发送的
*/</span>
main.m

<span style="font-size:18px;">//
//  main.m
//  通知和消息
//
//  Created by apple on 15/9/21.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Child.h"
#import "Nurse.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
[[Child alloc] init];
[[Nurse alloc] init];
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
</span>
运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: