通知中心

关于通知,最近在工作和学习中遇到了3个不太清楚的地方,经过网上查资料,和自我琢磨,终于把他该清楚了,现在分享给大家。

一.实例

首先建立一个测试案例。新建新建一个项目,在StoryBoard上托一个导航控制器为初始化控制器,其更控制器为一个TableViewController,在其根控制器上再连接一个ViewController,ViewController类上代码如下:

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     
 4     // 添加观察
 5     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextFieldTextDidChangeNotification object:nil];
 6 }
 7 
 8 - (void)dealloc {
 9     NSLog(@"88");
10 }
11 
12 - (void)textChanged:(NSNotification *)n {
13     
14     NSLog(@"睡 %@", [NSThread currentThread]);
15     [NSThread sleepForTimeInterval:1.0];
16     
17     static int num = 0;
18     NSLog(@"%@ %d", n, num++);
19 }
20 
21 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
22     // 发送通知
23     [[NSNotificationCenter defaultCenter] postNotificationName:UITextFieldTextDidChangeNotification object:@"hello"];
24     
25     NSLog(@"come here");
26 }

查询底层代码,可以看到通知是一个常量字符串。因此可以得到结论,通知中心本质上监听的是一个"字符串"

UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;

当程序运行后,导航栏左边按钮,初始化ViewController,单击屏幕,然后再点击返回按钮,返回导航控制器根控制器。

运行结果如下:

从运行结果中可以得到两个结论:

come here是最后输出的,因此可以确定通知是同步的。

当点击返回按钮时,dealloc执行,并输出"88",因此可以确定不删除观察者,程序也不会奔溃。

 但是仔细分析会发现,但是通知中心注册的仍然存在,事件发生的时候,仍然会广播,会有潜在的风险 

 1> vc 第一次实例化:0x0000abcd,在通知中心注册了,当发生事件的时候,通知中心会广播

 2> pop 出去,vc 被释放,通知中心并没有要求必须删除观察者

 3> vc 又一次被实例化:0x0000dcab,事件发生时,通知中心会继续广播给两个地址,有可能程序会崩溃

二.小结

  • 通知中心本质上监听的是一个"字符串"。
  • 通知是同步的,原因和 KVO 是一样的,保证所有的监听者能够及时作出响应!
  • 通知结束后,一定要删除观察者!
原文地址:https://www.cnblogs.com/cwhking/p/4185732.html