IOS开发:Notification与,多线程

   先来看看官方的文档,是这样写的:

  In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.

  翻译过来是:

  在多线程应用中,Notification在哪个线程中post,就在哪个线程中被转发,而不一定是在注册观察者的那个线程中。

  也就是说,Notification的发送与接收处理都是在同一个线程中。为了说明这一点,我们先来看一个示例:

  代码清单1:Notification的发送与处理

  @implementation ViewController

  - (void)viewDidLoad {

  [super viewDidLoad];

  NSLog(@"current thread = %@", [NSThread currentThread]);

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:TEST_NOTIFICATION object:nil];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  [[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil userInfo:nil];

  });

  }

  - (void)handleNotification:(NSNotification *)notification

  {

  NSLog(@"current thread = %@", [NSThread currentThread]);

  NSLog(@"test notification");

  }

  @end

  其输出结果如下:

  2015-03-11 22:05:12.856 test[865:45102] current thread = {number = 1, name = main}

  2015-03-11 22:05:12.857 test[865:45174] current thread = {number = 2, name = (null)}

  2015-03-11 22:05:12.857 test[865:45174] test notification

  可以看到,虽然我们在主线程中注册了通知的观察者,但在全局队列中post的Notification,并不是在主线程处理的。所以,这时候就需要注意,如果我们想在回调中处理与UI相关的操作,需要确保是在主线程中执行回调。

  这时,就有一个问题了,如果我们的Notification是在二级线程中post的,如何能在主线程中对这个Notification进行处理呢?或者换个提法,如果我们希望一个Notification的post线程与转发线程不是同一个线程,应该怎么办呢?我们看看官方文档是怎么说的:

  For example, if an object running in a background thread is listening for notifications from the user interface, such as a window closing, you would like to receive the notifications in the background thread instead of the main thread. In these cases, you must capture the notifications as they are delivered on the default thread and redirect them to the appropriate thread.

  这里讲到了“重定向”,就是我们在Notification所在的默认线程中捕获这些分发的通知,然后将其重定向到指定的线程中。

  一种重定向的实现思路是自定义一个通知队列(注意,不是NSNotificationQueue对象,而是一个数组),让这个队列去维护那些我们需要重定向的Notification。我们仍然是像平常一样去注册一个通知的观察者,当Notification来了时,先看看post这个Notification的线程是不是我们所期望的线程,如果不是,则将这个Notification存储到我们的队列中,并发送一个信号(signal)到期望的线程中,来告诉这个线程需要处理一个Notification。指定的线程在收到信号后,将Notification从队列中移除,并进行处理。

  官方文档已经给出了示例代码,在此借用一下,以测试实际结果:

  • 1、
  • 2、
  • 3、
  • 4、
  • 5、
  • 6、
  • 7、
  • 8、
  • 9、
  • 10、
  • 11、
  • 12、
  • 13、
  • 14、
  • 15、
  • 16、
  • 17、
  • 18、
  • 19、
  • 20、
  • 21、
  • 22、
  • 23、
  • 24、
  • 25、
  • 1、
  • 2、
  • 3、
  • 4、
  • 5、
  • 6、
  • 7、
  • 8、
  • 9、
  • 10、
  • 11、
  • 12、
  • 13、
  • 14、
  • 15、
  • 16、
  • 17、
  • 18、
  • 19、
  • 20、
  • 21、
  • 22、
  • 23、
  • 24、
  • 25、