是否可以使用通知回到IOS应用程序的主线程? (比较performSelectorOnMainThread)

是否可以使用通知回到IOS应用程序的主线程? (比较performSelectorOnMainThread)。 也就是说,有什么gottcha这个目的?

背景

  • 想要从后台线程callback主UI线程(例如performSelectorInBackground)
  • 可以使用performSelectorOnMainThread进行通信,但想知道是否可以使用通知?

例如

[[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self]; 

其实有一个gottcha; 你会随机崩溃! 这是我的经验。 这与接收通知的对象在与通知的发送者相同的线程上这样做。

通知中心的Apple iOS文档 :

在multithreading应用程序中,通知总是在发布通知的线程中传递,而这些线程可能与观察者自己注册的线程不同。

这将不可避免地令你头痛。

如果主线程收到通知,我发现从后台线程popup进入主线程发出通知是最安全的方法。 这很简单:

 //Call this to post a notification and are on a background thread - (void) postmyNotification{ [self performSelectorOnMainThread:@selector(helperMethod:) withObject:Nil waitUntilDone:NO]; } //Do not call this directly if you are running on a background thread. - (void) helperMethod{ [[NSNotificationCenter defaultCenter] postNotificationName:@"SOMENAME" object:self]; } 

不幸的是,这引入了发送者和接收者之间的微妙耦合,因为你正在修改发送者以容纳接收者。

正如XJones所指出的,更好的解决scheme是让发送者在任何线程上发送通知,然后让侦听器负责使用正确的线程执行所需的任何操作。

希望有帮助。

是的,通知可以用于这个目的。 您可以使用任何您喜欢的方法(协议,通知,直接消息传递)来跨线程在对象之间进行通信。 你select哪一个取决于你觉得什么是最合适的。 当发布通知的对象不了解观察通知的对象时,通知是很好的。 如果你发送消息(例如performSelectorOnMainThread ),那么发送消息的对象确实需要知道它正在发送消息的对象(通常是通过协议)。