iOS-Objective-C

iOS中通知异步?同步?

2017-08-07  本文已影响28人  追沐

让人很纳闷的一个问题:通知是同步的还是异步的

在iOS开发中有人问“通知是同步的还是异步的”。个人感觉问的这个问题本身就有问题,你只能说通知的执行方法是同步的还是异步的,或者说发送通知是同步的还是异步的...对于通知是同步还是异步,这个问法本身就很笼统,让人不明白你是要问什么,所以很纳闷。

一个通知的小例子

这里我们用一个简单的小例子来看看通知的执行是在子线程还是在主线程。

1、 首先我们在viewDidLoad方法里面注册了一个通知:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:kTestNotificationName object:nil];
}

通知的注册者是self,执行方法是test,name是一个字符常量

static NSString *kTestNotificationName = @"TestNotification";

2、我们是在ViewController中测试的,借用touch方法来试试

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    dispatch_queue_t queue = dispatch_queue_create("CONCURRENT QUEUE", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
       
        [[NSNotificationCenter defaultCenter] postNotificationName:kTestNotificationName object:nil];
        
        NSLog(@"%@",[NSThread currentThread]);
    });
}

这里我们先写了一个队列CONCURRENT QUEUE,然后执行异步任务。异步任务里面我们发送通知。

3、test方法里打印

- (void)test {
    NSLog(@"test %@",[NSThread currentThread]);
}

4、打印结果

2017-08-07 16:55:16.987 Test[4333:191487] test <NSThread: 0x608000266e00>{number = 3, name = (null)}
2017-08-07 16:55:16.987 Test[4333:191487] <NSThread: 0x608000266e00>{number = 3, name = (null)}
2017-08-07 17:16:08.164 Test[4472:200122] test <NSThread: 0x60000007d6c0>{number = 1, name = main}
2017-08-07 17:16:08.165 Test[4472:200122] <NSThread: 0x60000007d6c0>{number = 1, name = main}

完整例子如下:

#import "ViewController.h"

static NSString *kTestNotificationName = @"TestNotification";

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //注册,主线程
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:kTestNotificationName object:nil];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //创建队列
    dispatch_queue_t queue = dispatch_queue_create("CONCURRENT QUEUE", DISPATCH_QUEUE_CONCURRENT);
    //执行异步任务
    dispatch_sync(queue, ^{
        
        [[NSNotificationCenter defaultCenter] postNotificationName:kTestNotificationName object:nil];
        
        NSLog(@"%@",[NSThread currentThread]);
    });
}

- (void)test {
    NSLog(@"test %@",[NSThread currentThread]);
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kTestNotificationName object:nil];
}
@end

例子中测试子线程中发送通知,看通知方法是在哪个线程中执行;我们可以将异步任务改成同步任务,看看在主线程中发送通知,确认一下执行方法是在主线程。

总结

上一篇 下一篇

猜你喜欢

热点阅读