iOS 通知(NSNotification)的简单使用

通知:NSNotification,是iOS开发中一种重要的设计模式,它的实质是程序内部提供的一种广播机制。把接受到的消息根据内部消息转发表,将消息转发给需要的对象。

通知这种设计模式,在开发中常用来不同类之间的通信,也就是常说的页面之间的传值。当然它不仅仅只有这一种应用场景,还有一种常用场景是用来控制一些属性或者控件,使得这些属性或控件在不同情况下发生响应的变化。在我以前的一个项目中就有这样的场景出现:

项目需求:每次打开app和每次需要下载时监控网络状态变化,当时WiFi状态是打开自动下载开关,非WiFi状态时关闭自动下载开关。

对于这样的需求,就可以使用通知去实现,而且很简单,只需要在需要发送通知的地方,注册、发送通知,在开关存在的地方接受通知消息,根据通知去控制开关是开启还是关闭。

那么,下面介绍如何使用通知。

首先先介绍一下几个类:

1、NSNotification

这个类是通知类,由这个类创建的对象是一个通知对象,也可以理解为是一个消息对象。类中有三个成员变量:

name:是消息对象的唯一标识,接受通知消息时用来辨别

@property (readonly,copy)NSNotificationName name;

object:一个对象,可以理解为针对某个对象的消息

@property (nullable,readonly,retain)id object;

userInfo:一个字典,用来传值

@property (nullable,readonly,copy)NSDictionary *userInfo;

NSNotification初始化:

对象方法初始化一个通知对象,并给通知对象的属性赋值

- (instancetype)initWithName:(NSNotificationName)name object:(nullableid)object userInfo:(nullableNSDictionary *)userInfoNS_AVAILABLE(10_6, 4_0) NS_DESIGNATED_INITIALIZER;

类方法创建一个通知对象,这个方法没有userInfo这个属性的初始赋值,所以用来发送无传值的通知

+ (instancetype)notificationWithName:(NSNotificationName)aName object:(nullableid)anObject;

类方法初始化一个通知对象,并给通知对象的属性赋值

+ (instancetype)notificationWithName:(NSNotificationName)aName object:(nullableid)anObject userInfo:(nullableNSDictionary *)aUserInfo;

注意:NSNotification不可以使用init进行初始化。

2、NSNotificationCenter

这个类是通知中心类,内部实现是单利模式,每个程序都有一个默认的通知中心,用来调度通知的发送和接受。

通知中心类相关方法:

a、接收通知的方法:

添加观察者,可以指定一个方法、名称和对象,接受到通知时执行这个指定的方法。这里的name就是通知类的name,只有对应才能接受到通知。

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

b、发送通知的方法:

发送通知,参数是一个通知对象

- (void)postNotification:(NSNotification *)notification;

发送通知,参数是通知的名称,指定的对象

- (void)postNotificationName:(NSNotificationName)aName object:(nullableid)anObject;

发送通知,参数是通知的名称,指定的对象和传递的参数

- (void)postNotificationName:(NSNotificationName)aName object:(nullableid)anObject userInfo:(nullableNSDictionary *)aUserInfo;

上面这三个方法虽然写法不同,但是功能一样,使用哪一个方法取决于NSNotification类如何创建对象。后两种方法其实就是初始化通知并发送通知,将通知对象的初始化和发送方法结合。

c、移除通知的方法:

移除该检测对象(observer)下的所有通知

- (void)removeObserver:(id)observer;

根据通知名称(aName),移除该检测对象(observer)下的一个通知

- (void)removeObserver:(id)observer name:(nullableNSNotificationName)aName object:(nullableid)anObject;

一个通知的初始化,发送,接收。就是对上面这些方法的使用。

下面,示例说明:

#import "ViewController.h"

@interface ViewController ()

{

    UILabel *label;

    UIButton *button;

}

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    

    //创建视图方法

    [selfsetUI];

    //创建通知中心对象

    NSNotificationCenter *center = [NSNotificationCenterdefaultCenter];

    //注册、接收通知

    [center addObserver:selfselector:@selector(chanegeLabelText:)name:@"notification"object:nil];

}

- (void)setUI{

    label = [[UILabelalloc]initWithFrame:CGRectMake(100, 200, 200, 30)];

    label.backgroundColor = [UIColoryellowColor];

    label.text =@"没有接收到通知";

    [self.viewaddSubview:label];

    

    button = [UIButtonbuttonWithType:UIButtonTypeCustom];

    button.frame =CGRectMake(100, 300, 200, 30);

    [buttonsetTitle:@"发送通知"forState:UIControlStateNormal];

    [buttonsetBackgroundColor:[UIColorblueColor]];

    [buttonaddTarget:selfaction:@selector(post)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:button];

}

//按钮点击方法

- (void)post{

    //初始化一个通知对象,名称是 notification  没有指定对象  穿的值是一个字典@{@"key":@"an object"}

    NSNotification *notification = [NSNotificationnotificationWithName:@"notification"object:niluserInfo:@{@"key":@"接收到了通知"}];

    

    [[NSNotificationCenterdefaultCenter]postNotification:notification];

}

//接收通知后调用的方法

- (void)chanegeLabelText:(NSNotification *)noti{

    //这个方法的参数就是发送通知postNotification:方法的参数发送过来额通知。当要使用传递的userInfo的时候,就要使用noti解析出userInfo中需要的字段

    label.text = [noti.userInfoobjectForKey:@"key"];

}

- (void)viewDidDisappear:(BOOL)animated{

   [super viewDidDisappear:animated];

    //在页面消失的回调方法中移除通知。

    [[NSNotificationCenterdefaultCenter]removeObserver:selfname:@"notification"object:nil];

}

@end

点击按钮前:                      点击按钮后:

      

在上面的显示中可以看到代码没有问题。

上面的示例只是为了介绍通知的使用而写的,在实际开发中并不会有这样实现功能的做法。通知的使用是为了实现不同控制器,或者不同类之间的通信从而实现一些解耦。在同一个类中一般是没有信息传递的。

而且,要牢记一点,通知既然是程序内部的一种广播机制,那么它的存在就是通信。

关于通知的使用就是,注册、接收通知(addObserver)--->发送通知(postNotification)--->移除通知(removeObserver)。

这里关于移除通知和前面的KVO那篇文章中移除KVO一样,要在合理的位置移除。

猜你喜欢

转载自blog.csdn.net/m0_37681833/article/details/68064700