2

私はこの小さなプログラムを書きました。このプログラムは、現在の最前面のアプリケーションを 2 回印刷し、その間に 3 秒の休憩を挟みます。

void printFrontmostApp() {
    NSRunningApplication *frontmostApplication = [NSWorkspace sharedWorkspace].frontmostApplication;
    NSLog(@"%@",frontmostApplication);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        printFrontmostApp();
        sleep(3);
        printFrontmostApp();
    }
    return 0;
}

このプログラムを実行すると、2 回目の呼び出し時に frontmostApplication が更新されないことに気付きました。ここで解決策を見つけました。しかし、まだ 2 つの質問があります。

1) frontmostApplication が更新されない理由を知りたい。

2) 呼び出すたびに強制的に更新するにはどうすればよいですか? 最前面のアプリケーションが非アクティブになるたびに通知を受け取りたくありません。私の目的には少し非効率的だからです。

編集: 明確にするために、現在の時刻が 10:00:00 であるとしましょう。printFrontmostApp を呼び出すと、コンソールに "Xcode" が出力されます。これは、Xcode が現在最前面にあるアプリであるためです。その後、プログラムは 3 秒間スリープします。10:00:01 に、TextEdit などの別のアプリを開きました。10:00:03 に、私のプログラムは printFrontmostApp を 2 回呼び出します。現在の最前線のアプリケーションである「TextEdit」を印刷することを期待しています。ただし、代わりに「Xcode」を出力します。この振る舞いが理解できません。

誰かが 10:00:03 に何が起こったのか説明してもらえますか? この関数は、10:00:00 の frontmostApplication の値を「記憶」しているようで、2 回目に呼び出されたときにそれを保持します。範囲外になるとメモリが解放されると思っていたのに、なぜこれが起こっているのですか?

また、プログラムで 10:00:03 に最前面のアプリを取得するにはどうすればよいでしょうか? 10:00:00 に最前面のアプリを取得できますが、3 秒後に同じことができるはずですよね?

4

2 に答える 2

1

使用している方法ではなく、関連するドキュメントに-[NSWorkspace runningApplications]は、次のように記載されています。

クラスのプロパティと同様にNSRunningApplication、このプロパティは、メインの実行ループが共通モードで実行されている場合にのみ変更されます。ポーリングの代わりに、キーと値の監視を使用して、この配列プロパティへの変更が通知されるようにします。

NSRunningApplicationドキュメントから:

時間の経過とともに変化するプロパティは、本質的に競合しやすいものです。たとえば、非表示のアプリはいつでも再表示できます。これを改善するために、共通モードでメイン実行ループの次のターンまでプロパティが持続します。たとえば、実行ループの実行を許可せずに、非表示にされていないアプリの隠しプロパティを繰り返しポーリングすると、実行NOループの次のターンまで、アプリが非表示になっていても、アプリは を返し続けます。

-frontmostApplicationドキュメントに明示されていなくても、同じ原則が適用されることはほぼ確実です。実行ループの実行を許可せずにポーリングしても、異なる結果が得られることはありません。

于 2015-10-28T15:41:01.323 に答える
1

1) の場合、回答はリンクした質問に記載されているものと同じです: 新しいアプリケーションがいつアクティブ化されたかを通知するこの通知を確認する必要があります:

NSWorkspaceDidActivateApplicationNotification

2) について:

NSWorkspaceDidDeactivateApplicationNotification

したがって、登録されていないという通知を確認することはできません。包括的なリストについては、NSWorkspace 通知を参照してください。

それ以外の場合は、更新/ポーリングに関する質問を定義してください (とにかく、それは良い考えではないと思います)。

于 2015-10-28T14:12:03.513 に答える