Notification多线程 重定向
来源:互联网 发布:java面试笔试题及答案 编辑:程序博客网 时间:2024/06/14 13:27
如果我们的Notification是在二级线程中post的,如何能在主线程中对这个Notification进行处理呢?或者换个提法,如果我们希望一个Notification的post线程与转发线程不是同一个线程,应该怎么办呢?
“重定向”:
就是我们在Notification所在的默认线程中捕获这些分发的通知,然后将其重定向到指定的线程中。
一种重定向的实现思路是自定义一个通知队列(注意,不是NSNotificationQueue对象,而是一个数组),让这个队列去维护那些我们需要重定向的Notification。我们仍然是像平常一样去注册一个通知的观察者,当Notification来了时,先看看post这个Notification的线程是不是我们所期望的线程,如果不是,则将这个Notification存储到我们的队列中,并发送一个信号(signal)到期望的线程中,来告诉这个线程需要处理一个Notification。指定的线程在收到信号后,将Notification从队列中移除,并进行处理
@interface ViewController ()<NSMachPortDelegate>
@property (nonatomic)NSMutableArray * notifications; // 通知队列
@property (nonatomic)NSThread * notificationThread; // 期望线程
@property (nonatomic)NSLock * notificationLock; // 用于对通知队列加锁的锁对象,避免线程冲突
@property (nonatomic)NSMachPort * notificationPort; // 用于向期望线程发送信号的通信端口
@end
@implementation ViewController
- (void)viewDidLoad
{
[superviewDidLoad];
NSLog(@"current thread = %@", [NSThreadcurrentThread]);
// 初始化
self.notifications = [[NSMutableArrayalloc] init];
self.notificationLock = [[NSLockalloc] init];
self.notificationThread = [NSThreadcurrentThread];
self.notificationPort = [[NSMachPortalloc] init];
self.notificationPort.delegate =self;
// 往当前线程的run loop添加端口源
// 当Mach消息到达而接收线程的run loop没有运行时,则内核会保存这条消息,直到下一次进入run loop
[[NSRunLoopcurrentRunLoop] addPort:self.notificationPort
forMode:(__bridgeNSString *)kCFRunLoopCommonModes];
[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(processNotification:)name:@"TestNotification"object:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[NSNotificationCenterdefaultCenter] postNotificationName:TEST_NOTIFICATIONobject:@""userInfo:nil];
});
}
- (void)handleMachMessage:(void *)msg {
[self.notificationLocklock];
while ([self.notificationscount]) {
NSNotification *notification = [self.notificationsobjectAtIndex:0];
[self.notificationsremoveObjectAtIndex:0];
[self.notificationLockunlock];
[selfprocessNotification:notification];
[self.notificationLocklock];
};
[self.notificationLockunlock];
}
- (void)processNotification:(NSNotification *)notification {
if ([NSThreadcurrentThread] != _notificationThread) {
// Forward the notification to the correct thread.
[self.notificationLocklock];
[self.notificationsaddObject:notification];
[self.notificationLockunlock];
[self.notificationPortsendBeforeDate:[NSDatedate]
components:nil
from:nil
reserved:0];
}
else {
// Process the notification here;
NSLog(@"current thread = %@", [NSThreadcurrentThread]);
NSLog(@"process notification");
}
}
运行后,其输出如下:
2015-03-11 23:38:31.637 test[1474:92483] current thread = {number = 1, name = main}
2015-03-11 23:38:31.663 test[1474:92483] current thread = {number = 1, name = main}
2015-03-11 23:38:31.663 test[1474:92483] process notification
可以看到,我们在全局dispatch队列中抛出的Notification,如愿地在主线程中接收到了
- Notification多线程 重定向
- C#重定向 进程调用 WinForm多线程
- C#重定向 进程调用 WinForm多线程
- C#重定向 进程调用 WinForm多线程
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- 重定向
- PowerDesigner提示Existence of index、key、reference错误
- 内部类无法声明
- 解决 requestFeature() must be called before adding content
- android 切换卡顿解决方法
- Linux驱动之input子系统
- Notification多线程 重定向
- Http请求地址
- MySQL百万级数据库查询优化技巧
- 字符串和数组的反转和排序
- uva 10626 Buying Coke (DP记忆化搜索)
- Python里str函数和repr函数的区别
- VS 项目文件 .vcxproj 文件 工程自定义宏
- linux中的 inode 详解
- OC中运行时的概念