iOS中的自定义通知和通知传值的简单介绍

来源:互联网 发布:js获取鼠标点击位置 编辑:程序博客网 时间:2024/06/06 12:37

一、通知

通知中心实际上是在程序内部提供了消息广播的一种机制。通知中心不能在进程间进行通信。实际上就是一个二传手,把接收到的消息,根据内部的一个消息转发表,来将消息转发给需要的对象。通知中心是基于观察者模式的,它允许注册、删除观察者。
一个NSNotificationCenter可以有许多的通知消息NSNotification,对于每一个NSNotification可以有很多的观察者Observer来接收通知。

通知可以在对象之间进行消息的传递,当然也可以进行参数值的传递,而且通知是一对多的模式,在一些特殊情况下特别有用。

二、通知使用的完整步骤

通常使用通知主要包含着四个步骤

1.创建一个通知对象

方法a:

//实例化一个通知对象,名为name,userInfo为携带信息的字典NSNotification *notification=nil;notification=[NSNotification notificationWithName:@"name" object:self userInfo:[NSDictionary dictionaryWithObject:@"可以自定义的字典,就是要发送的数据" forKey:@"xinxi"]];

方法b:

//不带携带信息的字典NSNotification *notification=nil;notification=[NSNotification notificationWithName:@"name" object:self];

注意:NSNotification对象也是不可变的,因为一旦创建,对象是不能更改的。

2.注册通知的监听者

//注册名为name的通知的监听,xiangYing:为收到通知的调用接口,是需要实现的方法[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xiangYing:) name:@"name" object:nil];
需要注意的是,有时候我们无法保证注册监听的类是否实现了xiangying:方法,所以应该检测一下之后再注册监听,完整代码如下

if([self respondsToSelector:@selector(xiangYing:)])    {
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xiangYing:) name:@"name" object:nil];
    }

PS:一般情况需要指定name和object,但如果仅仅指定了一个object,观察者将收到该对象的所有通知。例如将上面的代码中name改为nil,那么观察者将接收到object对象的所有消息,但是确定不了接收这些消息的顺序。如果指指定一个通知名称,观察者将收到它每次发出的通知。例如,上面的代码中object为nil,那么客户对象(self)将收到任何对象发出的@“name”通知。如果既没有指定指定object,也没有指定name,那么该观察者将收到所有对象的所有消息。


3.发送通知

方法1:

[[NSNotificationCenter defaultCenter] postNotification:notification];
方法2:

也可以不通过发送通知的对象,直接发送通知

[[NSNotificationCenter defaultCenter]postNotificationName:@"name" object:self userInfo:[NSDictionary dictionaryWithObject:@"可以自定义的字典" forKey:@"xinxi"]];

注意:每一个程序都有一个自己的通知中心,即NSNotificationCenter对象。该对象采用单例设计模式,采用defaultCenter方法就可以获得唯一的NSNotificationCenter对象。

4.移除通知

-(void)dealloc{    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"name" object:nil];}
注意参数notificationObserver为要删除的观察者,一定不能置为nil。


PS:这里简单说一下通知中心保存的调度表。通知中心的调度表是给一些观察者指定的一些通知集。一个通知集是通知中心发出的通知的子集。每个表的入口包含:通知观察者(必须要的)、通知名称、通知的发送者。最后,提醒一下观察者收到通知的顺序是没有定义的。同时通知发出和观察的对象有可能是一样的。


三、下面通过代码举个例子

首先建立一个项目,一个主页面ViewController(同时也是监听者)和另一个监听者TwoViewController以及一个通知的发送者类OneViewController

1.OneViewController.m中要实现发送通知,内部实现,如代码:

在viewDidLoad中,调用fasong方法

//这个方法可以根据需求在该页面等的任何地方调用 [self fasong];

这里只是为了从前一个页面一跳到这个页面就发送通知,所以写在了viewDidLoad中,节省时间;fasong方法的实现如下

-(void)fasong{    //先给实例化一下(two可以弄成属性,不一定非要在这里实例化)    TwoViewController *two=[[TwoViewController alloc]init];    NSLog(@"%@",two);//调用自带描述方法        //这里使用第一种方法,带参数,因为主要演示传值(notification也可以弄成属性,不用非在这里建立)    NSNotification *notification=nil;    notification=[NSNotification notificationWithName:@"name" object:self userInfo:[NSDictionary dictionaryWithObject:@"可以自定义的字典,就是要发送的数据" forKey:@"xinxi"]];        //发送通知,在哪里写都行,根据需求    [[NSNotificationCenter defaultCenter] postNotification:notification];}

2.主页面ViewController.m中加一个按钮,点击跳转到OneViewController,并把ViewController注册为监听者,实现代码如下

注册监听者

if ([self respondsToSelector:@selector(xiangYing:)])    {//注册名为name的通知的监听,xiangYing:为收到通知的调用接口,是需要实现的方法        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xiangYing:) name:@"name" object:nil];    }

添加按钮

    self.myButton=[UIButton buttonWithType:UIButtonTypeCustom];    self.myButton.frame=CGRectMake(100, 100, 50, 50);    self.myButton.layer.borderWidth=1;    self.myButton.layer.borderColor=[[UIColor redColor]CGColor];    [self.myButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];    [self.myButton addTarget:self action:@selector(myButtonAction) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:self.myButton];

按钮响应事件

-(void)myButtonAction{    OneViewController *one=[[OneViewController alloc]init];    [self presentViewController:one animated:YES completion:nil];}

接收到通后知响应事件

//接收到通知执行操作-(void)xiangYing:(NSNotification*)notif{    NSDictionary *dic=[notif userInfo];    NSLog(@"我是main,我收到了通知,通知内容:%@",dic[@"xinxi"]);}

移除通知监听代码

-(void)dealloc{    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"name" object:nil];}
3.在TwoViewController.m中的代码与在ViewController.m中的一致(除去添加按钮和按钮响应事件的代码),这里省略不写


好了,运行一下,出现主页,点击按钮跳转到OneViewController页面,并且出现打印信息,如下

2015-05-15 15:31:14.448 通知[2390:122986] <TwoViewController: 0x7fbb08d69f80>2015-05-15 15:31:14.449 通知[2390:122986] 我是main,我收到了通知,通知内容:可以自定义的字典,就是要发送的数据2015-05-15 15:31:14.450 通知[2390:122986] 我是one,我收到了通知,通知内容:可以自定义的字典,就是要发送的数据

成功,这就说明,通知可以给项目中任何已经实例化的对象传递数据,包括向前传递,完全没有问题。


PS:通知、代理和代码块都可以进行页面切换间的反向传值,通知传值是针对一对多的传值(可以同时对多个对象传递消息),代理和代码块则基本上是针对一对一的传值。







2 0
原创粉丝点击