NSNotificationCenter Observer перестает получать события, когда приложение не в фокусе на Lion

У меня есть приложение, которое подписывается на определенный вид уведомлений из NSNotificationCenter по умолчанию.

В OSX Lion это работает нормально, за исключением того, что когда приложение теряет фокус (другое приложение становится активным), оно перестает получать события. Когда приложение получает фокус, оно снова начинает получать события. Приложение не имело такого поведения в предыдущих версиях OSX, оно всегда получало уведомления, даже когда оно было не в фокусе.

Что я могу сделать, чтобы изменить это поведение?

Спасибо! Натан


person nbarraille    schedule 15.11.2011    source источник


Ответы (3)


Я знаю, что немного поздно отвечать на этот вопрос, все еще для моих записей и если кто-то все еще ищет.

У моего приложения панели меню OS X была такая же проблема. Я хотел, чтобы приложение наблюдало за всеми состояниями.

Причина:

Когда приложение теряет фокус, наблюдатель приостанавливается.

т.е. Когда приложение становится неактивным, оно вызывает метод

-(void)applicationDidResignActive:(NSNotification *)notification

и по умолчанию объект NSDistributedNotificationCenter приостанавливается.

Решение: я создал объект для NSDistributedNotificationCenter.

NSDistributedNotificationCenter *center=[NSDistributedNotificationCenter defaultCenter];

а затем, когда приложение теряет фокус, вызывается метод applicationDidResignActive, и внутри него объект NSDistributedNotificationCenter восстанавливается из приостановленного состояния, отправляя NO методу setSuspended.

-(void)applicationDidResignActive:(NSNotification *)notification
{
    [center setSuspended:NO];
}

а затем приложение начинает наблюдать, даже когда теряет фокус.

person Vipin Johney    schedule 02.04.2013
comment
Работает для приложения Mac OS X Menu, как описано! Если бы я мог, я бы проголосовал за него на 100+. Спасибо, вы спасли мой день! 3 часа тестирования и, наконец, ваше решение помогло мне понять, почему я не могу получать уведомления, когда мое приложение неактивно. Спасибо еще раз! - person edukulele; 21.07.2015

Согласно NSDistributionNotificationCenter ссылке https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDistributedNotificationCenter_Class/Reference/Reference.html#//apple_ref/doc/uid/20000396-BCICEHHB

Класс NSApplication автоматически приостанавливает доставку распределенных уведомлений, когда приложение неактивно. Приложения, основанные на платформе Application Kit, должны позволять AppKit управлять приостановкой доставки уведомлений. Программы, предназначенные только для Foundation, могут время от времени нуждаться в использовании этого метода.

Вы также можете

установите поведение наблюдателя при приостановке на NSNotificationSuspensionBehaviorDeliverImmediately с помощью

- (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(NSString *)notificationSender suspensionBehavior:(NSNotificationSuspensionBehavior)suspendedDeliveryBehavior

или установите deliverImmediately в YES при публикации

- (void)postNotificationName:(NSString *)notificationName object:(NSString *)notificationSender userInfo:(NSDictionary *)userInfo deliverImmediately:(BOOL)deliverImmediately

отправлять уведомления немедленно в приостановленном состоянии.

И убедитесь, что вы периодически не убиваете distnoted. Я забыл, что у меня есть старый скрипт агента запуска для killall distnoted, чтобы избежать утечек памяти.

person mash    schedule 03.08.2014

Похоже, что поведение по умолчанию при добавлении наблюдателя в NSDistributedNotificationsCenter изменилось на NSNotificationSuspensionBehaviorCoalesce, который не доставляет уведомления, когда приложение неактивно.

Описано здесь: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDistributedNotificationCenter_Class/Reference/Reference.html#//apple_ref/doc/uid/20000396-5567

person nbarraille    schedule 15.11.2011