iOS-NSNotificationCenter通知中心是同步操作还是异步操作

时间:2022-05-18 23:51:12

前言

最近有个小伙伴到喜马拉雅去面试,面试官问他一个问题就是“通知中心是同步操作还是异步操作?”,小伙伴回答成异步了,然后就是回家等消息,然后就是没有然后了。。。

我先举几个小的列子给大家瞅瞅:

发送通知

- (void)sentValueBtnClick:(UIButton *)button{
    NSLog(@"发送通知");
    NSDictionary *dict = @{@"myValue":@"ZFJ通知传值"};
    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"KPassValue" object:nil userInfo:dict]];
}

接收通知

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _textField.layer.borderColor = [UIColor redColor].CGColor;
    _textField.layer.borderWidth = 1.0;
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(passValue:) name:@"KPassValue" object:nil];
}

- (void)passValue:(NSNotification *)text{
    NSString *valueStr = text.userInfo[@"myValue"];
    NSLog(@"收到值:%@",valueStr);
    sleep(3);
    self.textField.text = valueStr;
    NSLog(@"通知赋值完毕");
}

打印结果:

2017-04-24 14:36:42.043 NSNotification[8150:145628] 发送通知

2017-04-24 14:36:42.043 NSNotification[8150:145628] 收到值:ZFJ通知传值

2017-04-24 14:36:45.044 NSNotification[8150:145628] 通知赋值完毕


案例分析

通过打印我们可以看出,当我们发送通知以后,观察者在接收到值以后,我们休眠3秒,程序才会继续往下执行,也就是说这个过程是同步的;我认为这里面设计为同步,是考虑到这一点,那就是一个通知可能有多个监听者,采用同步的方式能够保证所有的观察者都能够对通知做出相应,不会遗漏。

异步操作

如果我们想异步操作怎么办呢?莫急且看下面:

发送通知:

- (void)sentValueBtnClick:(UIButton *)button{
    NSLog(@"发送通知");
    NSDictionary *dict = @{@"myValue":@"ZFJ通知传值"};
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"KPassValue" object:nil userInfo:dict]];
    });
}

接受通知:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _textField.layer.borderColor = [UIColor redColor].CGColor;
    _textField.layer.borderWidth = 1.0;
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(passValue:) name:@"KPassValue" object:nil];
}

- (void)passValue:(NSNotification *)text{
    NSString *valueStr = text.userInfo[@"myValue"];
    NSLog(@"收到值:%@",valueStr);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(3);
        self.textField.text = valueStr;
        NSLog(@"通知赋值完毕");
    });
}

我们发布通知在子线程里面发布,当然接收也要在子线程里面接收了。。。


欢迎大家讨论和补充。。。