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

Gre*_*reg 13 iphone nsnotifications nsthread nsnotificationcenter ios

是否可以使用通知回复到IOS应用程序的主线程?(cf performSelectorOnMainThread).也就是说,为此目的有没有任何gottcha?

背景

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

例如

 [[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self];
Run Code Online (Sandbox Code Playgroud)

Pix*_*dSt 20

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

通知中心Apple iOS文档:

在多线程应用程序中,通知始终在发布通知的线程中传递,这可能与观察者注册自己的线程不同.

这将不可避免地让你头疼.

如果主线程上的某些东西收到了通知,我发现从后台线程弹出主线程发出通知是最安全的方法.这很简单:

//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];
}
Run Code Online (Sandbox Code Playgroud)

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

正如XJones所指出的,更好的解决方案是让发送者在其决定的任何线程上发出通知,然后让监听器负责使用正确的线程来执行它需要的任何操作.

希望这很有帮助.


XJo*_*nes 8

是的,通知可以用于此目的.您可以使用任何您喜欢的方法(协议,通知,直接消息传递)来跨线程在对象之间进行通信.您选择哪一个取决于您认为最合适的.当发布通知的对象对观察通知的对象一无所知时,通知很有用.如果您发送消息(例如performSelectorOnMainThread),则发送消息的对象确实需要知道它正在发送消息的对象(通常通过协议).