Оба синхронны, но почему функция NotificationQueue может «игнорировать» дубликаты уведомлений? - PullRequest
0 голосов
/ 06 октября 2019

Почему NotificationQueue.PostingStyle.now можно удалить с помощью коалесценции, но NotificationCenter.default не может узнать, приходят ли другие уведомления или нет? Объединение уведомлений по темам программирования уведомлений говорит, что «его поведение является синхронным - уведомления отправляются перед возвратом», и оба его поведения являются синхронными, так как может (почему только) поставить в очередь (_notification, NotificationQueue.PostingStyle, coalesceMask:NotificationQueue.NotificationCoalescing, forModes mode: [RunLoop.Mode]?) Функция знает, что приходят уведомления?

Я просто проверил, что вызовы методов синхронны: перед тем, как объект публикации может возобновить поток выполнения, он должен ждать, пока центр уведомлений не отправит уведомление всем наблюдателям и не вернется. У кого-нибудь есть ответ на это? Любая помощь подойдет. Заранее спасибо!

1 Ответ

1 голос
/ 06 октября 2019

Первый абзац документации NotificationQueue дает вам подсказку -

В то время как центр уведомлений распределяет уведомления при их публикации, уведомления, помещенные в очередь, могут быть отложены доконец текущего прохода через цикл выполнения или до тех пор, пока цикл выполнения не будет свободен. Дублирующиеся уведомления могут быть объединены, так что отправляется только одно уведомление, хотя отправляется несколько уведомлений.

A NotificationQueue не может объединять уведомления бесконечно, это можно сделать только до конца текущего прогонаПередача цикла или до тех пор, пока цикл выполнения не будет свободен.

Указание .now для стиля проводки гласит:

Уведомление публикуется сразу после объединения.

Поскольку вы доставляете уведомление немедленно, оно не может объединиться с любыми уведомлениями, которые еще не были помещены в очередь, но оно может объединить любые уведомления, которые все еще находятся в очереди;Уведомления, поставленные в очередь с .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")

При этом будет напечатано:

Полученное уведомление

Опубликовано

Получено уведомление

Опубликовано

Получено уведомление

Опубликовано

Начиная с postingStyle из.now не допускает никакого coaelscing.

Теперь рассмотрим:

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")

Это напечатает:

Опубликовано

Опубликовано

Размещено

Получено уведомление

Поскольку три уведомления могут быть объединены до их доставки, когда цикл выполнения простаивает. Вы можете увидеть то же поведение с .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")

Это напечатает:

Опубликовано

Опубликовано

Полученное уведомление

Отправлено

Первые два уведомления в очереди могут быть объединены с окончательным уведомлением, так как они все еще находятся в очереди, ожидая цикла выполнения. холостой ход. Одно уведомление будет немедленно доставлено на NotificationCenter.

Таким образом, если вы всегда используете .now для postingStyle, то NotificationQueue будет вести себя по существу так же, как отправка уведомления непосредственно наNotificationCenter, но если вы используете другой стиль публикации, тогда уведомления в очереди могут быть объединены в одно уведомление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...