Objective-C:正在刷新 FrontmostApplication
Objective-C: Refreshing 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) 我想知道为什么 frontmostApplication 没有更新。
2) 如何在每次调用时强制刷新?我不想在最前面的应用程序每次停用时都收到通知,因为它对我的目的来说效率有点低。
编辑:
只是为了 crystal 清楚,我们假设现在的时间是 10:00:00。我调用 printFrontmostApp,它将 "Xcode" 打印到控制台,因为 Xcode 是当前最前面的应用程序。然后程序休眠 3 秒。在 10:00:01,我打开了另一个应用程序,比如 TextEdit。在 10:00:03,我的程序第二次调用 printFrontmostApp。我希望它打印 "TextEdit",这是当前最前面的应用程序。但它会打印 "Xcode" 。我无法理解这种行为。
有人可以解释一下 10:00:03 发生了什么吗?该函数似乎"remember" 10:00:00处的frontmostApplication的值,并在第二次调用时保留它。我以为任何内存一旦超出范围就会被释放,所以为什么会这样?
以及如何让我的程序在 10:00:03 处获得最前面的应用程序?我可以在 10:00:00 获得最前面的应用程序,我应该可以在 3 秒后做同样的事情吧?
对于 1) 的答案与您所链接的问题中描述的相同:您必须观察此通知,它告诉您新应用程序何时被激活:
NSWorkspaceDidActivateApplicationNotification
关于 2) 您有不同的激活和停用观察者,例如:
NSWorkspaceDidDeactivateApplicationNotification
因此您不会看到您未注册的通知,请查看 NSWorkspace Notifications 以获得完整列表。
否则,请定义您关于 refreshing/polling 的问题(我认为这无论如何都不是一个好主意)。
documentation for -[NSWorkspace runningApplications]
— 不是您使用的方法,而是相关的 — 说:
Similar to the NSRunningApplication
class’s properties, this property will only change when the main run loop is run in a common mode. Instead of polling, use key-value observing to be notified of changes to this array property.
来自NSRunningApplication
documentation:
Properties that vary over time are inherently race-prone. For example, a hidden app may unhide itself at any time. To ameliorate this, properties persist until the next turn of the main run loop in a common mode. For example, if you repeatedly poll an unhidden app for its hidden property without allowing the run loop to run, it will continue to return NO
, even if the app hides, until the next turn of the run loop.
几乎可以肯定,同样的原则也适用于 -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) 我想知道为什么 frontmostApplication 没有更新。
2) 如何在每次调用时强制刷新?我不想在最前面的应用程序每次停用时都收到通知,因为它对我的目的来说效率有点低。
编辑: 只是为了 crystal 清楚,我们假设现在的时间是 10:00:00。我调用 printFrontmostApp,它将 "Xcode" 打印到控制台,因为 Xcode 是当前最前面的应用程序。然后程序休眠 3 秒。在 10:00:01,我打开了另一个应用程序,比如 TextEdit。在 10:00:03,我的程序第二次调用 printFrontmostApp。我希望它打印 "TextEdit",这是当前最前面的应用程序。但它会打印 "Xcode" 。我无法理解这种行为。
有人可以解释一下 10:00:03 发生了什么吗?该函数似乎"remember" 10:00:00处的frontmostApplication的值,并在第二次调用时保留它。我以为任何内存一旦超出范围就会被释放,所以为什么会这样?
以及如何让我的程序在 10:00:03 处获得最前面的应用程序?我可以在 10:00:00 获得最前面的应用程序,我应该可以在 3 秒后做同样的事情吧?
对于 1) 的答案与您所链接的问题中描述的相同:您必须观察此通知,它告诉您新应用程序何时被激活:
NSWorkspaceDidActivateApplicationNotification
关于 2) 您有不同的激活和停用观察者,例如:
NSWorkspaceDidDeactivateApplicationNotification
因此您不会看到您未注册的通知,请查看 NSWorkspace Notifications 以获得完整列表。
否则,请定义您关于 refreshing/polling 的问题(我认为这无论如何都不是一个好主意)。
documentation for -[NSWorkspace runningApplications]
— 不是您使用的方法,而是相关的 — 说:
Similar to the
NSRunningApplication
class’s properties, this property will only change when the main run loop is run in a common mode. Instead of polling, use key-value observing to be notified of changes to this array property.
来自NSRunningApplication
documentation:
Properties that vary over time are inherently race-prone. For example, a hidden app may unhide itself at any time. To ameliorate this, properties persist until the next turn of the main run loop in a common mode. For example, if you repeatedly poll an unhidden app for its hidden property without allowing the run loop to run, it will continue to return
NO
, even if the app hides, until the next turn of the run loop.
几乎可以肯定,同样的原则也适用于 -frontmostApplication
,即使文档没有明确说明。在不允许 运行 循环到 运行.