多线程与通知
Posted 火海夕
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程与通知相关的知识,希望对你有一定的参考价值。
总结:
1、同一线程,添加多个观察者或者发送多次通知,就会响应多次方法
2、不管创建在哪个线程,发送在哪个线程接收就在哪个线程
3、接收在哪个线程可以由添加方法发来控制
4、接收在哪个线程可以由添加runloop端口的方法来控制
#import "ViewController.h"
#define TEST_NOTIFICATION @"TestNotification"
@interface ViewController ()<NSMachPortDelegate>
@property (nonatomic) NSMutableArray *notifications; // 通知队列
@property (nonatomic) NSThread *notificationThread; // 期望线程
@property (nonatomic) NSLock *notificationLock; // 用于对通知队列加锁的锁对象,避免线程冲突
@property (nonatomic) NSMachPort *notificationPort; // 用于向期望线程发送信号的通信端口
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
// [self test5];
// [self test4];
// [self test3];
// [self test2];
// [self test1];
#pragma mark -添加一个观察者,发送两次响应两次
-(void)test5
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstNotification:) name:TEST_NOTIFICATION object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];
#pragma mark - 添加多个观察者,发送一次响应两次
-(void)test4
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstNotification:) name:TEST_NOTIFICATION object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstNotification:) name:TEST_NOTIFICATION object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];
#pragma mark - 发送在子线程,接收在主线程(可以指定某一个线程,不一定非要主线程)
-(void)test3
[[NSNotificationCenter defaultCenter] addObserverForName:TEST_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note)
NSLog(@"接收和处理通知的线程%@", [NSThread currentThread]);
];
dispatch_async(dispatch_get_global_queue(0, 0), ^
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];
NSLog(@"发送通知的线程为%@", [NSThread currentThread]);
);
#pragma mark - 发送在子线程,接收在主线程(接收在添加port所在loop的线程)
-(void)test2
NSLog(@"当前线程 = %@", [NSThread currentThread]);
// 初始化
self.notifications = [[NSMutableArray alloc] init];
self.notificationLock = [[NSLock alloc] init];
self.notificationThread = [NSThread currentThread];
self.notificationPort = [[NSMachPort alloc] init];
self.notificationPort.delegate = self;
// 往当前线程的run loop添加端口源
// 当Mach消息到达而接收线程的run loop没有运行时,则内核会保存这条消息,直到下一次进入run loop
[[NSRunLoop currentRunLoop] addPort:self.notificationPort
forMode:(__bridge NSString *)kCFRunLoopCommonModes];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(secondNotification:) name:TEST_NOTIFICATION object:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
NSLog(@"发送线程 = %@", [NSThread currentThread]);
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];
);
//notificationPort代理方法
- (void)handleMachMessage:(void *)msg
NSLog(@"%s",__func__);
[self.notificationLock lock];
while ([self.notifications count])
NSNotification *notification = [self.notifications objectAtIndex:0];
[self.notifications removeObjectAtIndex:0];
[self.notificationLock unlock];
[self secondNotification:notification];
[self.notificationLock lock];
;
[self.notificationLock unlock];
- (void)secondNotification:(NSNotification *)notification
NSLog(@"%s",__func__);
if ([NSThread currentThread] != _notificationThread)
// Forward the notification to the correct thread.
[self.notificationLock lock];
[self.notifications addObject:notification];
[self.notificationLock unlock];
[self.notificationPort sendBeforeDate:[NSDate date]
components:nil
from:nil
reserved:0];
else
// Process the notification here;
NSLog(@"接收线程 = %@", [NSThread currentThread]);
NSLog(@"通知流程结束");
#pragma mark - 创建在同一个线程,发送和接收在一个线程
-(void)test1
NSLog(@"当前线程为%@", [NSThread currentThread]);//0
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstNotification:) name:TEST_NOTIFICATION object:nil];
dispatch_async(dispatch_get_global_queue(0, 0), ^
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];
NSLog(@"发送通知的线程为%@", [NSThread currentThread]);//1
);
- (void)firstNotification:(NSNotification *)notification
NSLog(@"接收线程%@", [NSThread currentThread]);//1
@end
以上是关于多线程与通知的主要内容,如果未能解决你的问题,请参考以下文章
Java 多线程 :入门- 线程间协作:挂起当前线程(wait)与通知其他线程继续执行(notify notifyAll)