Расширение дремоты приложения

Когда пользователи работают с многократными приложениями одновременно, дремота приложения может сохранить энергию. Дремота приложения является автоматической в OS X; Вы должны ничего не сделать для Дремоты Приложения для работы с приложением. Но Дремота Приложения не может восполнить энергетические эффекты плохо разработанных приложений. К счастью, с очень небольшим усилием, можно использовать Дремоту Приложения API и другой APIs AppKit, чтобы расширить и улучшить его возможности, активно сокращая использование энергии и дальнейшее удлинение времени мобильные пользователи могут выполнить приложение, не включая питание переменным током.

Самый важный способ улучшить Дремоту Приложения состоит в том, чтобы прислушаться к уведомлениям, что окна Вашего приложения скрыты и приостановить интенсивную питанием работу, когда они не видимы — задолго до того, как система отправляет Ваше приложение в режим App Nap.

Когда поместить приложение в режим App Nap путем различения важные инициируемые пользователями действия и дискреционные или асинхронные действия приложения, можно также помочь системе определить:

Поймите то, что дремота приложения делает и не делает

Если приложение не выполняет важную пользовательскую работу (такую как получение, игра музыки или загрузка файла), система может отправить приложение в режим App Nap, сохраняющий время работы от батареи путем регулирования использования CPU приложения и путем сокращения частоты, с которой запущены ее таймеры. Энергетическое влияние режима App Nap проиллюстрировано на рисунке 3-1. Как только пользователь продолжает взаимодействовать с приложением, OS X немедленно смещает приложение назад к полной скорости.

  Нулевое энергетическое влияние рисунка 3-1 приложения в режиме App Nap

Для любого приложения, не выполняющего важную пользовательскую работу, Дремота Приложения инициировала много мер, включая:

Обратите внимание на то, что это не обязательно энергосберегающие меры; они прежде всего сокращают влияние неприоритетного приложения на другие приложения. Не полагайтесь на Дремоту Приложения для получения приложения к полностью неактивному.

OS X использует ряд эвристики для определения, когда поместить приложение в режим App Nap. Эта эвристика принимает во внимание факторы, такие как рисование действия, обработки событий, воспроизведения аудио, приоритетного или фонового состояния и типа приложения. Обычно приложение считается кандидатом на режим App Nap если:

Когда вышеупомянутым условиям удовлетворяют, OS X может поместить приложение в режим App Nap. Когда пользователь приносит приложение к переднему плану или когда приложение получает сообщение Маха или событие Apple, приложение автоматически вынуто из режима App Nap и возобновляет нормальное выполнение.

Путем фокусировки системных ресурсов на самой важной пользовательской работе Дремота Приложения дает пользователям опыт очень быстро реагирующей системы, а также значительное время работы от батареи. Следующее видео (рисунок 3-2) иллюстрирует, как Дремота Приложения сохраняет время работы от батареи при поставке быстро реагирующей системы. (С 2013 WWDC выбираются это видео и другие в этой главе: Повышение Эффективности Питания с Дремотой Приложения.)

Рисунок 3-2  демонстрация Дремоты Приложения

Знайте, когда Ваше приложение будет в режиме дремоты приложения

При разработке и тестировании приложения, у Вас есть два инструмента, которые могут помочь Вам определить, является ли Ваше приложение в режиме App Nap: энергетическое Влияние измеряет в XCode и энергетической области в приложении Монитора Действия.

Энергетический прибор Влияния. Когда Вы создаете и выполняете свое приложение в XCode, можно проверить взрывы таймера с энергетическим прибором Влияния. Откройтесь навигатор отладки (выберите View> Navigators> Show Debug Navigator). Выберите энергетический прибор Влияния. Когда приложение находится в режиме App Nap, как показано на рисунке 3-3, на энергетическом графике временной шкалы Влияния указывают зеленые панели.

  Энергетическая временная шкала Влияния рисунка 3-3 с приложением в режиме App Nap

Монитор действия. При тестировании, запуск приложение с выполнением приложения Монитора Действия. Нажмите энергетическую кнопку в Мониторе Действия и просмотрите состояние своего приложения в столбце App Nap. На рисунке 3-4 приложение ObjectPath выбрано в Мониторе Действия, и слово No в столбце App Nap указывает, что ObjectPath в настоящее время находится не в режиме App Nap.

  Монитор Действия рисунка 3-4, показывающий состояние App Nap для приложений

Минимизируйте работу, когда Ваше приложение не будет видимо

Даже, прежде чем система помещает Ваше приложение в режим App Nap, можно сразу остановить интенсивные действия питания, как только приложение или любое из его окон становятся скрытыми от пользователя. Когда Ваше приложение станет видимым снова, сразу обновите его содержание и возобновите любые интенсивные действия питания. Например, когда ее окно полностью покрыто или закрыто, Фотоавтомат выключает камеру и прекращает представлять графические эффекты.

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

Ваше приложение не видимо под следующими видами обстоятельств:

Для получения уведомлений об изменениях в видимости приложения реализуйте applicationDidChangeOcclusionState: метод в окне Вашего приложения управляет делегатом. После получения уведомления от этого метода Ваше приложение должно проверить ли NSApplicationOcclusionStateVisible постоянный установлен, как показано в логическом потоке Перечисления 3-1.

  Проверка перечисления 3-1 видимость приложения с applicationDidChangeOcclusionState метод

@implementation EYEAppDelegate
- (void)applicationDidChangeOcclusionState:(NSNotification *)n
{
 if ([NSApp occlusionState] & NSApplicationOcclusionStateVisible) {
  // the app is visible; continue doing work
} else {
  // the app is not visible; stop doing work }
}
@end

Если NSApplicationOcclusionStateVisible постоянный установлен (TRUE), это означает, что, по крайней мере, часть окна, принадлежавшего Вашему приложению, видима, таким образом, Ваше приложение могло бы продолжать работать. Если эта константа не установлена (FALSE), это означает, что никакая часть любого окна, принадлежавшего Вашему приложению, не видима; Ваше приложение должно остановить свои операции и вычисления, потому что пользователь не будет в состоянии видеть результаты.

Обратите внимание на то, что строка меню не рассчитывает как окно принадлежавший Вашему приложению, поэтому если только его строка меню показывает, система полагает, что Ваше приложение закрывается (NSApplicationOcclusionStateVisible постоянный установлен). Однако, если Ваше приложение создает элемент состояния, это присутствует в строке меню, Ваше приложение считают видимым (постоянный, не установлен), как долго, поскольку строка меню видима, потому что тот элемент состояния может иметь значение пользователю.

Видео на рисунке 3-5 демонстрирует, как остановить работу приложения, когда это становится покрытым окном другого приложения. (С 2013 WWDC выбирается это видео: Повышение Эффективности Питания с Дремотой Приложения.)

Рисунок 3-5  Используя applicationDidChangeOcclusionState метод для расширения эффективности использования энергии Дремоты Приложения

Для оптимального энергосбережения реализуйте windowDidChangeOcclusionState: метод в Вашем окне делегирует для получения уведомлений об изменениях в видимости окна. При получении уведомлений проверьте ли NSWindowOcclusionStateVisible постоянный установлен. Если это установлено, по крайней мере часть окна видима. Если константа не установлена, никакая часть окна не видима, и Ваше приложение должно остановить всю работу, выполняемую в том окне.

(Окно, имеющее непрямоугольную форму, может быть полностью покрыто на экране, но если ее ограничительная рамка попадает в видимую область, окно считается видимым. Абсолютно прозрачное окно можно также считать видимым.)

Улучшите дремоту приложения информированием системы о долгих действиях

Можно улучшить результаты эвристики Дремоты Приложения при помощи NSProcessInfo объект. Этот подход позволяет Вам отличать дискреционную работу, которую Ваше приложение инициирует от долгих инициируемых пользователями действий, таких как экспорт файлов или запись аудио. Когда Ваше приложение выполняет инициируемые пользователями действия, система не помещает Ваше приложение в режим App Nap. Долгие действия - те, которые продержались пяти или десяти секундам, или даже минутам, не тем длительные миллисекунды.

Вызовите beginActivityWithOptions:reason: метод прежде, чем выполнить асинхронные операции. Передайте возвращенный объект endActivity: когда закончено действие. options параметр для этого метода описывает вид действия, которое выполняет Ваше приложение. Если работа является инициируемым пользователем, можно передать NSActivityUserInitiated постоянный, как показано в Перечислении 3-2. Если работа является дискреционной или работой по техобслуживанию, передача NSActivityBackground постоянный.

Перечисление 3-2  вызывая beginActivityWithOptions метод для информирования системы о пользовательском действии

NSOperationQueue *queue = ...;
id token = [[NSProcessInfo processInfo]
             beginActivityWithOptions:NSActivityUserInitiated
             reason:@"Batch processing files"];
[queue addOperationWithBlock:^{
   // Perform batch processing of files here
   [[NSProcessInfo processInfo] endActivity:token];
}];

Для продолжительных синхронных операций вызовите performActivityWithOptions:reason:usingBlock: метод. Укажите вид действия и выполните его работу в блоке. Метод выполняет блок синхронно и автоматически начинает и заканчивает действие вокруг блока.

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

Видео на рисунке 3-6 демонстрирует, как использовать beginActivityWithOptions:reason: метод. В этом примере приложение передает NSActivityUserInitiatedAllowingIdleSystemSleep постоянный, чтобы указать, что приложение выполняет требуемое пользователями действие, но что система может спать на неактивном. (С 2013 WWDC выбирается это видео: Повышение Эффективности Питания с Дремотой Приложения.)

Рисунок 3-6  , Указывающий инициируемое пользователями действие, предотвращающее режим App Nap, когда скрыто окно приложения

Предотвратите дремоты с осторожностью

В то время как Ваше приложение выполняет длинные инициируемые пользователями операции, можно препятствовать тому, чтобы система приостановила эти операции или отправила приложение в режим App Nap путем передачи любой из четырех констант (перечисленный в Таблице 3-1) к beginActivityWithOptions:reason: и performActivityWithOptions:reason:usingBlock: методы.

Табличный 3-1  Сон и завершение управляют константами

Постоянный (со ссылкой к документации)

Описание

NSActivityIdleSystemSleepDisabled

Препятствуйте тому, чтобы система ввела неактивный системный сон

NSActivityIdleDisplaySleepDisabled

Препятствуйте тому, чтобы система ввела неактивный сон дисплея

NSActivitySuddenTerminationDisabled

Предотвратите внезапное завершение

NSActivityAutomaticTerminationDisabled

Предотвратите автоматическое завершение

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

Если необходимо предотвратить системный сон или сон дисплея, несомненно, проверят во время тестирования, что получающиеся утверждения управления питанием Набора I/O отбрасываются, когда они не необходимы. Они описаны в Ссылке IOPMLib.h.

Чтобы видеть, имеют ли Ваши процессы какие-либо утверждения питания в действительности при выполнении приложения от Терминала, вводят команду pmset -g assertions. В примере в Перечислении 3-3 предотвращение неактивного пользователя и системный сон утверждалось Глазным приложением. Строка отладки “Batch processing files” сообщаемый в выводе был предоставлен в reason параметр к beginActivityWithOptions:reason:.

  Тестирование перечисления 3-3 на утверждения управления питанием

$ pmset -g assertions
Assertion status system-wide:
  BackgroundTask                 0
  PreventUserIdleDisplaySleep    0
  PreventSystemSleep             0
  PreventDiskIdle                0
  PreventUserIdleSystemSleep     1
  ExternalMedia                  0
  UserIsActive                   0
  ApplePushServiceTask           0
Listed by owning process:
  pid 1963(Eyes): [0x0000000100000196] 00:03:36 PreventUserIdleSystemSleep named: "Batch processing files"