在iOS開(kāi)發(fā)中大家使用通知時(shí)不知道有沒(méi)有人想過(guò)一個(gè)問(wèn)題;子線程的發(fā)出的通知會(huì)在哪個(gè)線程執(zhí)行呢?
今天我們就來(lái)驗(yàn)證一下,廢話不多說(shuō)直接上代碼
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_queue_create("com.dd", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 在子線程中發(fā)出通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"notification" object:nil];
NSLog(@"發(fā)出通知線程==%@",[NSThread currentThread]);
});
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(observerFun) name:@"notification" object:nil];
}
- (void)observerFun{
// 在主線程中監(jiān)聽(tīng)通知
NSLog(@"接受通知線程==%@",[NSThread currentThread]);
}
打印結(jié)果

1.png
可以看出中子線程發(fā)出的通知也是在子線程執(zhí)行的,那如果是在主線程發(fā)出的通知呢?
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_queue_create("com.dd", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 在子線程中監(jiān)聽(tīng)通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(observerFun) name:@"notification" object:nil];
});
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 在主線程中發(fā)出通知
NSLog(@"發(fā)出通知線程==%@",[NSThread currentThread]);
[[NSNotificationCenter defaultCenter] postNotificationName:@"notification" object:nil];
}
- (void)observerFun{
NSLog(@"接受通知線程==%@",[NSThread currentThread]);
}
打印結(jié)果

2.png
可以看到主線程發(fā)出的通知接受通知執(zhí)行代碼的線程同樣也是在主線程.
所以我們可以得出結(jié)論:接收通知代碼執(zhí)行的線程是由發(fā)出通知線程決定!
你以為這就完了嗎?下面這段代碼卻不是適用上面這個(gè)結(jié)論。
// queue:決定block在哪個(gè)線程執(zhí)行,nil:在發(fā)布通知的線程中執(zhí)行
// [NSOperationQueue mainQueue]: 在主線程執(zhí)行
// [NSOperationQueue new]: 在子線程執(zhí)行
[[NSNotificationCenter defaultCenter] addObserverForName:@"notification" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
NSLog(@"接受通知線程==%@",[NSThread currentThread]);
}];
如果你用上面這段代碼時(shí),接受通知執(zhí)行的線程就不由發(fā)出通知的線程決定了,通過(guò)queue參數(shù)可以自己決定block里的代碼在哪個(gè)線程執(zhí)行。驗(yàn)證的過(guò)程我就不寫(xiě)了,大家可以自己去試一試.
最終結(jié)論: