Расширение дремоты приложения
Когда пользователи работают с многократными приложениями одновременно, дремота приложения может сохранить энергию. Дремота приложения является автоматической в OS X; Вы должны ничего не сделать для Дремоты Приложения для работы с приложением. Но Дремота Приложения не может восполнить энергетические эффекты плохо разработанных приложений. К счастью, с очень небольшим усилием, можно использовать Дремоту Приложения API и другой APIs AppKit, чтобы расширить и улучшить его возможности, активно сокращая использование энергии и дальнейшее удлинение времени мобильные пользователи могут выполнить приложение, не включая питание переменным током.
Самый важный способ улучшить Дремоту Приложения состоит в том, чтобы прислушаться к уведомлениям, что окна Вашего приложения скрыты и приостановить интенсивную питанием работу, когда они не видимы — задолго до того, как система отправляет Ваше приложение в режим App Nap.
Когда поместить приложение в режим App Nap путем различения важные инициируемые пользователями действия и дискреционные или асинхронные действия приложения, можно также помочь системе определить:
Когда Ваше приложение передает это, оно выполняет дискреционные действия, система эффективно помещает Ваше приложение в режим App Nap.
Когда Ваше приложение говорит системе, что пользователь инициировал продолжительную работу, которую пользователь ожидает завершать «теперь», система не помещает Ваше приложение в режим App Nap.
Поймите то, что дремота приложения делает и не делает
Если приложение не выполняет важную пользовательскую работу (такую как получение, игра музыки или загрузка файла), система может отправить приложение в режим App Nap, сохраняющий время работы от батареи путем регулирования использования CPU приложения и путем сокращения частоты, с которой запущены ее таймеры. Энергетическое влияние режима App Nap проиллюстрировано на рисунке 3-1. Как только пользователь продолжает взаимодействовать с приложением, OS X немедленно смещает приложение назад к полной скорости.

Для любого приложения, не выполняющего важную пользовательскую работу, Дремота Приложения инициировала много мер, включая:
Приоритетное сокращение, сокращающее приоритет процесса приложения так, чтобы это получило меньшую долю доступного процессорного времени
Регулировка таймера, сокращающая частоту, с которой запущены таймеры приложения
Регулировка I/O, сокращающая уровень, на котором приложение может считать или записать данные из устройства, в то время как для приоритетных приложений нужно устройство
Обратите внимание на то, что это не обязательно энергосберегающие меры; они прежде всего сокращают влияние неприоритетного приложения на другие приложения. Не полагайтесь на Дремоту Приложения для получения приложения к полностью неактивному.
OS X использует ряд эвристики для определения, когда поместить приложение в режим App Nap. Эта эвристика принимает во внимание факторы, такие как рисование действия, обработки событий, воспроизведения аудио, приоритетного или фонового состояния и типа приложения. Обычно приложение считается кандидатом на режим App Nap если:
Это не приоритетное приложение
Это недавно не вовлекло видимую часть окна
Это не является слышимым
Это не взяло утверждений управления питанием Набора I/O
Когда вышеупомянутым условиям удовлетворяют, OS X может поместить приложение в режим App Nap. Когда пользователь приносит приложение к переднему плану или когда приложение получает сообщение Маха или событие Apple, приложение автоматически вынуто из режима App Nap и возобновляет нормальное выполнение.
Путем фокусировки системных ресурсов на самой важной пользовательской работе Дремота Приложения дает пользователям опыт очень быстро реагирующей системы, а также значительное время работы от батареи. Следующее видео (рисунок 3-2) иллюстрирует, как Дремота Приложения сохраняет время работы от батареи при поставке быстро реагирующей системы. (С 2013 WWDC выбираются это видео и другие в этой главе: Повышение Эффективности Питания с Дремотой Приложения.)
Знайте, когда Ваше приложение будет в режиме дремоты приложения
При разработке и тестировании приложения, у Вас есть два инструмента, которые могут помочь Вам определить, является ли Ваше приложение в режиме App Nap: энергетическое Влияние измеряет в XCode и энергетической области в приложении Монитора Действия.
Энергетический прибор Влияния. Когда Вы создаете и выполняете свое приложение в XCode, можно проверить взрывы таймера с энергетическим прибором Влияния. Откройтесь навигатор отладки (выберите View> Navigators> Show Debug Navigator). Выберите энергетический прибор Влияния. Когда приложение находится в режиме App Nap, как показано на рисунке 3-3, на энергетическом графике временной шкалы Влияния указывают зеленые панели.

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

Минимизируйте работу, когда Ваше приложение не будет видимо
Даже, прежде чем система помещает Ваше приложение в режим App Nap, можно сразу остановить интенсивные действия питания, как только приложение или любое из его окон становятся скрытыми от пользователя. Когда Ваше приложение станет видимым снова, сразу обновите его содержание и возобновите любые интенсивные действия питания. Например, когда ее окно полностью покрыто или закрыто, Фотоавтомат выключает камеру и прекращает представлять графические эффекты.
По умолчанию Ваше приложение становится имеющим право на режим App Nap после того, как это не вовлекало видимое окно в течение некоторого отрезка времени, иногда до одной минуты. Путем проявления более превентивного подхода Вы улучшаете энергосберегающие функции Дремоты Приложения, Вы удлиняете время, Ваши пользователи могут выполнить Ваше приложение, не включая питание переменным током, и Вы способствуете существенной эффективности батареи платформы.
Ваше приложение не видимо под следующими видами обстоятельств:
Windows других приложений закрывает окна Вашего приложения
Экранная заставка идет (таким образом, закрывающий окна всех приложений)
Ваше приложение находится в месте на рабочем столе, где не работает пользователь
Для получения уведомлений об изменениях в видимости приложения реализуйте 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 выбирается это видео: Повышение Эффективности Питания с Дремотой Приложения.)
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 выбирается это видео: Повышение Эффективности Питания с Дремотой Приложения.)
Предотвратите дремоты с осторожностью
В то время как Ваше приложение выполняет длинные инициируемые пользователями операции, можно препятствовать тому, чтобы система приостановила эти операции или отправила приложение в режим App Nap путем передачи любой из четырех констант (перечисленный в Таблице 3-1) к beginActivityWithOptions:reason: и performActivityWithOptions:reason:usingBlock: методы.
Постоянный (со ссылкой к документации) | Описание |
|---|---|
Препятствуйте тому, чтобы система ввела неактивный системный сон | |
Препятствуйте тому, чтобы система ввела неактивный сон дисплея | |
Предотвратите внезапное завершение | |
Предотвратите автоматическое завершение |
Если Ваше приложение требует его для критических по отношению к задержке операций, можно также временно увеличить точность таймера планировщика при помощи 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" |