都是同步的,但是为什么函数的NotificationQueue可以“忽略”重复通知呢?
Both synchronous, but why the NotificationQueue of function can "ignoring” duplicate notifications?
为什么NotificationQueue.PostingStyle.now可以通过合并删除,但是NotificationCenter.default无法知道是否有更多通知到来?通知编程主题的合并通知说 "its behavior is synchronous—notifications are posted before returning" 并且它的行为都是同步的,那么如何(为什么只能) enqueue(_ notification: Notification, postingStyle: NotificationQueue.PostingStyle, coalesceMask: NotificationQueue.NotificationCoalescing , forModes 模式:[RunLoop.Mode]?) 函数知道通知即将到来?
我都简单地测试了方法的调用是同步的:在发布对象可以恢复其执行线程之前,它必须等到通知中心将通知分派给所有观察者和returns。
有人对此有答案吗?任何帮助都可以。提前致谢!
第一段NotificationQueue
documentation给你一个线索-
Whereas a notification center distributes notifications when posted, notifications placed into the queue can be delayed until the end of the current pass through the run loop or until the run loop is idle. Duplicate notifications can be coalesced so that only one notification is sent although multiple notifications are posted.
A NotificationQueue
不能无限期地合并通知,它只能这样做直到当前 运行 循环结束或直到 运行 循环空闲。
为发布样式指定 .now
表示:
The notification is posted immediately after coalescing.
由于您是立即传递通知,它不能与任何尚未排队的通知合并,但它可以合并仍在队列中的任何通知;使用 .whenIdle
或 .asap
发布样式排队的通知。
考虑以下片段:
NotificationCenter.default.addObserver(forName: .test, object: nil, queue: nil) { (notification) in
print("Received notification")
}
let queue = NotificationQueue.default
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
这将打印:
Received notification
Posted
Received notification
Posted
Received notification
Posted
因为 .now
的 postingStyle
不允许任何合并。
现在,考虑:
let queue = NotificationQueue.default
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
这将打印:
Posted
Posted
Posted
Received notification
因为当 运行 循环空闲时,三个通知可以在传送前合并。您会看到与 .asap
相同的行为
最后,考虑:
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
这将打印:
Posted
Posted
Received notification
Posted
前两个排队的通知可以与最后一个通知合并,因为它们仍在队列中等待 运行 循环空闲。一个通知将立即发送到 NotificationCenter
。
总而言之,如果您始终对 postingStyle
使用 .now
,那么 NotificationQueue
的行为与直接将通知发布到 NotificationCenter
的行为基本相同,但是如果您使用不同的发布方式,则排队的通知可能会合并为一个通知。
为什么NotificationQueue.PostingStyle.now可以通过合并删除,但是NotificationCenter.default无法知道是否有更多通知到来?通知编程主题的合并通知说 "its behavior is synchronous—notifications are posted before returning" 并且它的行为都是同步的,那么如何(为什么只能) enqueue(_ notification: Notification, postingStyle: NotificationQueue.PostingStyle, coalesceMask: NotificationQueue.NotificationCoalescing , forModes 模式:[RunLoop.Mode]?) 函数知道通知即将到来?
我都简单地测试了方法的调用是同步的:在发布对象可以恢复其执行线程之前,它必须等到通知中心将通知分派给所有观察者和returns。 有人对此有答案吗?任何帮助都可以。提前致谢!
第一段NotificationQueue
documentation给你一个线索-
Whereas a notification center distributes notifications when posted, notifications placed into the queue can be delayed until the end of the current pass through the run loop or until the run loop is idle. Duplicate notifications can be coalesced so that only one notification is sent although multiple notifications are posted.
A NotificationQueue
不能无限期地合并通知,它只能这样做直到当前 运行 循环结束或直到 运行 循环空闲。
为发布样式指定 .now
表示:
The notification is posted immediately after coalescing.
由于您是立即传递通知,它不能与任何尚未排队的通知合并,但它可以合并仍在队列中的任何通知;使用 .whenIdle
或 .asap
发布样式排队的通知。
考虑以下片段:
NotificationCenter.default.addObserver(forName: .test, object: nil, queue: nil) { (notification) in
print("Received notification")
}
let queue = NotificationQueue.default
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
这将打印:
Received notification
Posted
Received notification
Posted
Received notification
Posted
因为 .now
的 postingStyle
不允许任何合并。
现在,考虑:
let queue = NotificationQueue.default
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
这将打印:
Posted
Posted
Posted
Received notification
因为当 运行 循环空闲时,三个通知可以在传送前合并。您会看到与 .asap
最后,考虑:
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .whenIdle)
print("Posted")
queue.enqueue(Notification(name: .test), postingStyle: .now)
print("Posted")
这将打印:
Posted
Posted
Received notification
Posted
前两个排队的通知可以与最后一个通知合并,因为它们仍在队列中等待 运行 循环空闲。一个通知将立即发送到 NotificationCenter
。
总而言之,如果您始终对 postingStyle
使用 .now
,那么 NotificationQueue
的行为与直接将通知发布到 NotificationCenter
的行为基本相同,但是如果您使用不同的发布方式,则排队的通知可能会合并为一个通知。