常见的使用就不说了,说一说本身遇到的tipgit
这一点与KVO相似,即发送通知的时候,全部接收者都收到通知才算作发送完成。github
这一点与KVO相似。 NSNotification不能跨线程:即响应通知的action,默认是与postNotification在同一个线程的,若想在指定线程中执行响应通知的方法,可使用带有block的addObserver方法,或者使用dispatch_async(xxx)。segmentfault
若是须要跨线程,可使用带有block的通知接口。安全
如AFN中:bash
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, error);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
复制代码
为了保证在主线程发送通知。 这一点能够在一些网络请求数据到达时, 用于刷新界面。网络
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationFilterMaterialRequestFinished object:self userInfo:nil];
});
复制代码
为什么SDWebImage中对object使用weakSelfsession
FREQUENT CRASH in [SDWebImageDownloaderOperation cancelInternal] #1807多线程
使用queue和blockasync
使用mach port函数
上面说到,收发都在一个线程中,若是想要作到,在某个指定的线程接收通知,该如何作呢?苹果文档上说起了实现思路。
先简单介绍下mach port,它主要用来线程间通讯。简单来讲,就是接收线程中注册NSMachPort,在另外的线程中使用此port发送消息,则注册线程会收到相应消息,调用handleMachMessage来处理。
主要思路:
定义一个中间对象NotificationHandler,用来专门接收通知,包括一个队列,接收通知的线程,mach port,lock。
首先NotificationHandler会注册一个通知,对应的处理函数为processNotification,当在其余线程中post时,processNotification会被调用,进行以下处理。若是收到的通知跟指定的线程同样,则处理消息,反之,则添加到队列,同时经过port发送消息给指定线程。注意多线程中,对队列的处理,要加锁。
指定线程收到回调handleMachMessage,首先会将通知删除,而后调用processNotification进行处理,继续以上过程。