iOS中通知異步?同步?

讓人很納悶的一個問題:通知是同步的還是異步的

在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ā)送后找注冊者的這個過程是異步的吧?是不是這樣呢?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容