讓人很納悶的一個問題:通知是同步的還是異步的
在iOS開發(fā)中有人問“通知是同步的還是異步的”。個人感覺問的這個問題本身就有問題,你只能說通知的執(zhí)行方法是同步的還是異步的,或者說發(fā)送通知是同步的還是異步的...對于通知是同步還是異步,這個問法本身就很籠統(tǒng),讓人不明白你是要問什么,所以很納悶。
一個通知的小例子
這里我們用一個簡單的小例子來看看通知的執(zhí)行是在子線程還是在主線程。
1、 首先我們在viewDidLoad方法里面注冊了一個通知:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:kTestNotificationName object:nil];
}
通知的注冊者是self,執(zhí)行方法是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,然后執(zhí)行異步任務(wù)。異步任務(wù)里面我們發(fā)送通知。
3、test方法里打印
- (void)test {
NSLog(@"test %@",[NSThread currentThread]);
}
4、打印結(jié)果
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)}
- 打印結(jié)果顯示我們是在子線程中發(fā)送的通知,則通知的執(zhí)行方法也在子線程中執(zhí)行。
- 如果將上述線程改成主線程中發(fā)送通知的話,通知執(zhí)行方法就會在主線程中執(zhí)行,主線程中打印結(jié)果如下:
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
{
//創(chuàng)建隊列
dispatch_queue_t queue = dispatch_queue_create("CONCURRENT QUEUE", DISPATCH_QUEUE_CONCURRENT);
//執(zhí)行異步任務(wù)
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
例子中測試子線程中發(fā)送通知,看通知方法是在哪個線程中執(zhí)行;我們可以將異步任務(wù)改成同步任務(wù),看看在主線程中發(fā)送通知,確認(rèn)一下執(zhí)行方法是在主線程。
總結(jié)
發(fā)送通知是在哪個線程,則執(zhí)行通知的方法就在哪個線程中執(zhí)行。
對于有些人說“通知都是異步的”,我想了想可能這指的是通知發(fā)送后找注冊者的這個過程是異步的吧?是不是這樣呢?