У меня есть приложение для iOS, состоящее из нескольких библиотек и цели приложения. Приложение iOS можно запустить разными способами, например, нажав на файл, глубокую ссылку, универсальную ссылку, запустив из QuickAction и т. д. Информация о том, как оно было запущено, передается в сцену SceneDelegate(_:willConnectTo:options:). Теперь я хочу транслировать эту информацию всем библиотекам, которые раньше зарегистрировали бы наблюдателей.
Я подумываю использовать NotificationCenter , но в документации Apple есть следующая строка при получении экземпляра по умолчанию.
Если ваше приложение широко использует уведомления, возможно, вы захотите создать и опубликовать их в собственных центрах уведомлений, а не публиковать сообщения только в центре уведомлений по умолчанию. Когда уведомление публикуется в центре уведомлений, центр уведомлений просматривает список зарегистрированных наблюдателей, что может замедлить работу вашего приложения. Благодаря функциональной организации уведомлений вокруг одного или нескольких центров уведомлений каждый раз при публикации уведомления выполняется меньше работы, что может повысить производительность всего приложения.
Итак, вместо использования NotificationCenter по умолчанию, из которого мы получаем события жизненного цикла, такие как DidBecomeActiveNotification, я хотел создать собственный NotificationCenter. Но я не смог найти примеров того, как это сделать, даже в документации Apple.... где было упоминание об использовании специального NotificationCenter (как указано выше), но это все.
Я протестировал следующий код. Пользовательское уведомление создается путем создания экземпляра NotificationCenter, как показано ниже:
// Creating a custom notification centre
public static let notificationCenter: NotificationCenter = NotificationCenter()
При регистрации для получения уведомлений:
sQuickActionLaunchNotificationObserver = notificationCenter.addObserver(forName: Notification.Name("QUICK_ACTION_LAUNCH"), object: nil, queue: nil, using: handleNotificationBroadcasts)
func handleNotificationBroadcasts(_ broadcastNotification: Notification) {
// Handle the notification
}
Теперь, когда приложение запускается с помощью ярлыка, я передаю уведомление следующим образом:
// Somewhere in the SceneDelegate's scene(_:willConnectTo:options:), when app is launched using QuickAction (shortcut)
notificationCenter.post(name: Notification.Name("QUICK_ACTION_LAUNCH"), object: nil, userInfo["QuickActionKey":shortcutItem])
Я создаю собственный центр уведомлений (не использую центр по умолчанию), использую его для регистрации, а также для публикации уведомлений... и все это работает.
Но верен ли описанный выше подход? Я в замешательстве, потому что не смог получить никакой информации об использовании специального NotificationCenter для трансляции в документации Apple. Есть несколько примеров в Интернете, но в этих примерах люди создали подклассы и добавили некоторую функциональность. Но мне не нужны какие-либо дополнительные функции... Я создаю только новый экземпляр, потому что было рекомендовано создать собственный NotificationCenter, чтобы избежать влияния на производительность из-за слишком большого количества наблюдателей. Я только хочу проверить этот подход.
Тогда причина использования настраиваемого центра уведомлений состоит в том, чтобы избежать снижения производительности из-за добавления слишком большого количества наблюдателей. Это количество упоминается в документации (также цитируемой выше), но насколько это слишком много? У меня, вероятно, будет зарегистрировано 20-30 уведомлений (очень приблизительно), и в обработчике, который вызывается с помощью объекта Notification, я подумываю сначала перенести выполнение кода в фоновый поток, вернуть поток пользовательского интерфейса и продолжить обработку в фоновый поток..... поскольку поток пользовательского интерфейса должен быть возвращен как можно скорее. Итак, по сути, регистрация количества наблюдателей может повлиять на производительность?
Я создаю новый экземпляр только потому, что было рекомендовано создать собственный NotificationCenter, чтобы избежать снижения производительности из-за слишком большого количества наблюдателей. Я только хочу проверить этот подход. ... у меня наверное будет зарегистрировано 20-30 уведомлений (очень приблизительно)
Под «зарегистрированными» я предполагаю, что вы имеете в виду наблюдателей, а не уведомления. Это очень и очень небольшое количество наблюдателей. Используйте Центр уведомлений по умолчанию.
Я не рекомендую специализированные центры, и Apple тоже. До того, как ObjC добавил блоки (аналогично замыканиям Swift), с уведомлениями было проделано гораздо больше работы на гораздо менее мощном оборудовании, чем на современном iPhone. NSNotificationCenter восходит к NeXTSTEP. Сканирование большого списка наблюдателей в приложении, которое «широко» использует уведомления, может стать проблемой. Но это было бы крайне необычно для современного приложения Swift на iOS.
За почти 20 лет разработки Cocoa я только однажды перегрузил NSNotificationCenter. Однажды, много лет назад (задолго до Swift), я экспериментировал с выполнением всех обратных вызовов с помощью NSNotifications. В итоге у нас было около 5000 наблюдателей, которые размещали несколько уведомлений в секунду. Это сделало прокрутку немного медленной.
Сегодня вы бы никогда не построили что-то подобное (да и в то время это была не очень хорошая идея). Вам не нужен отдельный NotificationCenter, и, по моему опыту, наличие отдельного центра может привести к ошибкам. В конце концов вы отправляете сообщение не на тот адрес, и появляется симптом «ничего не происходит», который трудно отладить.