Objective-C:刷新FrontmostApplication

时间:2015-10-28 14:05:47

标签: objective-c nsrunningapplication

我写了这个小程序,应该打印当前最前面的应用程序两次,中间间隔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。我找到了解决方案here。但我还有两个问题:

1)我想知道为什么没有更新frontmostApplication。

2)每次调用它时,如何强制刷新?我不希望每次最前面的应用程序停用时都收到通知,因为它对我的目的来说效率有点低。

修改 为了清楚起见,我们假设现在的时间是10:00:00。我调用printFrontmostApp,它将“Xcode”打印到控制台,因为Xcode是当前最前面的应用程序。然后程序休眠3秒钟。在10:00:01,我打开另一个应用程序,说TextEdit。在10:00:03,我的程序第二次调用printFrontmostApp。我希望它打印“TextEdit”,这是当前最前面的应用程序。但它会打印“Xcode”。我无法理解这种行为。

有人可以解释一下10:00:03会发生什么吗?该函数似乎在10:00:00“记住”frontmostApplication的值,并在第二次调用时保留它。我认为任何内存一旦超出范围就会被释放,那么为什么会这样呢?

如何让我的程序在10:00:03获得最前端的应用程序?我可以在10:00:00获得最前面的应用程序,我应该可以在3秒后做同样的事情吗?

2 个答案:

答案 0 :(得分:0)

对于1)答案与您链接的问题中描述的相同:您必须遵守此通知,该通知会告诉您何时激活新应用程序:

NSWorkspaceDidActivateApplicationNotification

关于2)你有不同的观察员来激活和停用,如:

NSWorkspaceDidDeactivateApplicationNotification

因此,您不会观察到您未注册的通知,请查看NSWorkspace Notifications以获取完整列表。

否则,请定义关于刷新/轮询的问题(我认为这不是一个好主意)。

答案 1 :(得分:0)

documentation for -[NSWorkspace runningApplications] - 不是您正在使用但与之相关的方法 - 说:

  

NSRunningApplication类的属性类似,此属性仅在主运行循环以共同模式运行时才会更改。而不是轮询,使用键值观察来通知此数组属性的更改。

来自NSRunningApplication documentation

  

随时间变化的属性本身就容易出现竞争。例如,隐藏的应用程序可能随时取消隐藏。为了改善这种情况,属性会持续到主要运行循环的下一轮转为共同模式。例如,如果您反复轮询一个未隐藏的应用程序的隐藏属性而不允许运行循环运行,它将继续返回NO,即使该应用程序隐藏,直到下一轮运行循环。

几乎可以肯定的是,即使文档没有明确说明,同样的原则也适用于-frontmostApplication。在不允许运行循环的情况下进行轮询,您永远不会得到不同的结果。