通知中心(NSNotificationCenter)实际是在程序内部提供了一种广播机制。把接收到的消息,根据内部的消息转发表,将消息转发给需要的对象。这句话其实已经很明显的告诉我们要如何使用通知了。第一步:在需要的地方注册要观察的通知,第二步:在某地方发送通知。(这里注意:发送的通知可能是我们自定义的,也可能是系统的)。
一,使用通知
第1中创建通知方法
//注意,通知的使用是有先后顺序的
//一定要先监听通知,然后在发送通知
//第一种方法
// 添加一个通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotification) name:@"tongzhi" object:nil]; //发送一个通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
//发送通知也可以传递一些参数
[NSNotificationCenter defaultCenter] postNotificationName:<#(nonnull NSNotificationName)#> object:<#(nullable id)#> userInfo:<#(nullable NSDictionary *)#>
可以在监听的通知的方法获取通知的信息
- (void)addNotification { NSLog(@"接受通知");
}
最后要移除通知
- (void)dealloc { //移除观察者 self
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
第2种通知的使用使用 block 比较方便简单
这个方法需要一个id类型的值接受
@property (nonatomic, weak) id observe;
//第二种方法
//Name: 通知的名称
//object:谁发出的通知
//queue: 队列,决定 block 在哪个线程中执行, nil 在发布通知的线程中执行
//usingBlock: 只要监听到通知,就会执行这个 block
//这个通知返回一个 id 这个通知同样需要移除
_observe = [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
NSLog(@"收到了通知");
}]; [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
同样,这里也需要移除通知,但是这里的观察者不是 self 而是 _observe
- (void)dealloc { //移除观察者 _observe
[[NSNotificationCenter defaultCenter] removeObserver:_observe];
}
二 .通知在多线程中的使用
通知在多线程中使用
//通知在接收的方法跟发送通知所在的线程中一样
异步发送通知, 主线程监听通知, 接收通知的方法在子线程中
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //发送通知
dispatch_async(dispatch_get_global_queue(, ), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
});
} - (void)viewDidLoad {
[super viewDidLoad]; //多线程中使用通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotification) name:@"tongzhi" object:nil]; } - (void)addNotification {
NSLog(@"接受通知");
NSLog(@"%@",[NSThread currentThread]); //主线程:监听通知,异步发送通知
//总结: 接受通知的代码由发出通知的线程
//更新 UI
dispatch_sync(dispatch_get_main_queue(), ^{
//更新 UI
});
}
控制台输出 : 异步
-- ::05.537 通知多线程使用[:] 接受通知
-- ::05.538 通知多线程使用[:] <NSThread: 0x60800026d8c0>{number = , name = (null)}
主线程中发送通知,异步线程中监听通知
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //主线程中发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];
} - (void)viewDidLoad {
[super viewDidLoad]; //多线程中使用通知 //异步监听通知 dispatch_async(dispatch_get_global_queue(, ), ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotification) name:@"tongzhi" object:nil];
});
} - (void)addNotification {
NSLog(@"接受通知");
NSLog(@"%@",[NSThread currentThread]); //异步:监听通知,主线程发送通知
//总结: 接受通知的代码由发出通知的线程 }
控制台输出
-- ::40.160 通知多线程使用[:] 接受通知
-- ::40.160 通知多线程使用[:] <NSThread: 0x600000072ac0>{number = , name = main}
使用 block 创建通知的方法,
queue :[NSOperationQueue mainQueue] 这样都会在主线程中执行block 中代码
_observe = [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
NSLog(@"收到了通知");
}];
控制台输出 : 主线程中执行
-- ::39.277 通知多线程使用[:] 收到了通知
-- ::39.277 通知多线程使用[:] <NSThread: 0x60000006ea40>{number = , name = main}