74

我发现以下代码片段允许NSNotification从任何后台线程发布到主线程。我想知道这是否是一种安全且可接受的做法?

dispatch_async(dispatch_get_main_queue(),^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ImageRetrieved" 
                                                        object:nil 
                                                      userInfo:imageDict];
});
4

4 回答 4

66

是的,你可以

通常,您希望在 main 上发送 NSNotifications,尤其是当它们触发 UI 活动(例如关闭模式登录对话框)时。

向特定线程发送通知

定期通知中心在发布通知的线程上发送通知。分布式通知中心在主线程上传递通知。有时,您可能需要在由您而不是通知中心确定的特定线程上传递通知。例如,如果在后台线程中运行的对象正在侦听来自用户界面的通知,例如窗口关闭,您希望在后台线程而不是主线程中接收通知。在这些情况下,您必须捕获在默认线程上传递的通知并将它们重定向到适当的线程。

于 2013-04-04T14:19:14.893 回答
17

是的

这是 - 您正在进入主线程并发布您的通知。没有比这更安全的了。

于 2013-04-04T14:17:45.350 回答
15

是的

斯威夫特 2语法

dispatch_async(dispatch_get_main_queue()) {
    NSNotificationCenter.defaultCenter().postNotificationName("updateSpinner", object: nil, userInfo: ["percent":15])
}

斯威夫特 3语法

DispatchQueue.main.async {
    NotificationCenter.default.post(name: "updateSpinner", object: nil, userInfo: ["percent":15])
}
于 2015-11-11T10:28:43.923 回答
13

沿着这条线的某个地方,这成为可能:

addObserver(forName:object:queue:using:)

这是here,但重点是queue对象。

应该添加块的操作队列。如果您通过nil,则该块在发布线程上同步运行。

那么如何获取主runloop对应的队列呢?

let mainQueue = OperationQueue.main

注意:这是您订阅通知的时间,因此您只需执行一次即可。每次通话都这样做是非常多余的。

于 2017-03-15T04:03:34.523 回答