Цель-C: Обновление FrontmostApplication
Я написал эту маленькую программу, которая должна печатать текущее переднее приложение дважды с перерывом в 3 секунды.
void printFrontmostApp() {
NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;
NSLog(@"%@",frontmostApplication);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
printFrontmostApp();
sleep(3);
printFrontmostApp();
}
return 0;
}
Когда я запустил эту программу, я понял, что frontmostApplication не обновляется, когда он вызывается во второй раз. Я нашел решение здесь. Но у меня все еще есть два вопроса:
1) Я хочу знать, почему приложение frontmost не обновляется.
2) Как заставить его обновляться каждый раз, когда я его называю? Я не хочу получать уведомления каждый раз, когда отключается самое переднее приложение, потому что оно немного неэффективно для моих целей.
Изменить: Просто чтобы быть кристально чистым, давайте предположим, что время сейчас 10:00:00. Я вызываю printFrontmostApp, и он печатает "Xcode" на консоли, потому что Xcode является текущим самым передним приложением. Затем программа спит в течение 3 секунд. В 10:00:01 я открыл другое приложение, скажем, TextEdit. В 10:00:03 моя программа вызывает printFrontmostApp во второй раз. Я ожидаю, что это напечатает "TextEdit", который является текущим самым передним приложением. Но вместо этого он печатает "Xcode". Я не могу понять это поведение.
Может кто-нибудь объяснить, что происходит в 10:00:03? Кажется, что функция "запоминает" значение frontmostApplication в 10:00:00 и сохраняет его при повторном вызове. Я думал, что любая память будет освобождена, когда она выйдет из области видимости, так почему же это происходит?
И как я могу получить свою программу, чтобы получить самое переднее приложение в 10:00:03? Я могу получить самое переднее приложение в 10:00:00, я должен быть в состоянии сделать то же самое через 3 секунды, верно?
2 ответа
Документация для-[NSWorkspace runningApplications]
- не метод, который вы используете, но связанный - говорит:
Похож на
NSRunningApplication
Свойства класса, это свойство будет изменяться только тогда, когда основной цикл выполнения выполняется в обычном режиме. Вместо опроса используйте наблюдение значения ключа, чтобы получать уведомления об изменениях этого свойства массива.
От NSRunningApplication
документация:
Свойства, которые меняются со временем, по своей природе склонны к гонкам. Например, скрытое приложение может отобразить себя в любое время. Чтобы улучшить это, свойства сохраняются до следующего поворота основного цикла выполнения в обычном режиме. Например, если вы неоднократно опрашиваете скрытое приложение на предмет его скрытого свойства, не позволяя запустить цикл выполнения, оно продолжит возвращаться
NO
, даже если приложение скрывается, до следующего поворота цикла выполнения.
Это почти наверняка, что тот же принцип применяется к -frontmostApplication
хотя документация не говорит об этом явно. Вы никогда не получите другие результаты при опросе, не позволив запустить цикл выполнения.
Для 1) ответ тот же, что описан в вопросе, который вы связали: вы должны соблюдать это уведомление, которое сообщает вам, когда новое приложение было активировано:
NSWorkspaceDidActivateApplicationNotification
О 2) У вас есть разные наблюдатели для активации и деактивации, такие как:
NSWorkspaceDidDeactivateApplicationNotification
Так что вы не будете наблюдать уведомления о том, что вы не зарегистрированы, пожалуйста, взгляните на NSWorkspace Notifications для получения полного списка.
В противном случае, пожалуйста, задайте свой вопрос об обновлении / опросе (который я думаю, что это не очень хорошая идея в любом случае).