あなたの問題は、ブロック(または辞書)と関係があり、あなたがどのようにして(ab)-runningApplications
を使用しているかとは関係ありません。 docsから:NSRunningApplicationクラスのプロパティと同様に
、このプロパティ は本体のみ実行ループは共通モードで実行されたときに変更されます。 ポーリングの代わりに、キー値観測を使用して、 の変更がこの配列プロパティに通知されます。この目的を達成するために
、以下が適切な行動を示しています
#import "AppDelegate.h"
const static NSString *runningApplicationsContext = @"running applications observation";
@implementation AppDelegate
@synthesize window = _window;
- (void)dealloc
{
[[NSWorkspace sharedWorkspace] removeObserver:self
forKeyPath:@"runningApplications"
context:&runningApplicationsContext];
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[[NSWorkspace sharedWorkspace] addObserver:self
forKeyPath:@"runningApplications"
options:NSKeyValueObservingOptionNew
context:&runningApplicationsContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (context == &runningApplicationsContext) {
NSArray *runningApps = [(NSWorkspace *)object runningApplications];
NSMutableArray *appNames = [[NSMutableArray alloc] initWithCapacity:[runningApps count]];
for (NSRunningApplication *app in runningApps) {
[appNames addObject:[app localizedName]];
}
NSLog(@"%@", [[NSWorkspace sharedWorkspace] runningApplications]);
[appNames release];
}
}
これは、別の素敵な利点があります:あなたは、場合にあなたが興味を持っている、通知をトリガ何アプリケーション(複数可)を決定するためにchange
辞書を調べます。これにより、以前のrunningApplications
の結果がキャッシング/トラッキングから解放されます。
EDIT:あなたのコメントにアップした後、ここにあなたのブロックでだけで正常に動作し、いくつかのコードは、(私はあなたの大きなアプリで何かをしたと推定デッドコードを剥奪)の辞書に保存されているとオブザーバメソッドから呼び出さ:
#import "AppDelegate.h"
const static NSString *runningApplicationsContext = @"running applications observation";
@interface AppDelegate() {
NSDictionary *_blocks;
}
@end
@implementation AppDelegate
@synthesize window = _window;
- (void)dealloc
{
[[NSWorkspace sharedWorkspace] removeObserver:self
forKeyPath:@"runningApplications"
context:&runningApplicationsContext];
[_blocks release];
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
_blocks = [[NSDictionary alloc] initWithObjectsAndKeys:(id)
^{
NSLog(@"%@", [[NSWorkspace sharedWorkspace] runningApplications]);
}, @"RunningApplications",
nil];
[[NSWorkspace sharedWorkspace] addObserver:self
forKeyPath:@"runningApplications"
options:NSKeyValueObservingOptionNew
context:&runningApplicationsContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (context == &runningApplicationsContext) {
dispatch_block_t getRunningApplications = [_blocks objectForKey:@"RunningApplications"];
getRunningApplications();
}
}
@end
おかげさまで、ありがとうございました。私は 'runningApplications'のポーリングはこれを行う正しい方法ではないことを理解していますが、それが私が更新されたリストを取得していない理由ではないと私は信じています。以前にこのポーリングを行って更新リストを受け取った場合、問題は辞書からブロックにアクセスするときにのみ発生します。 – sud0
ブロック・イン・ディクショナリを実装したコードを投稿しましたが、悪影響はありません。あなたの問題は、あなたのポーリング方法が何らかの形で実行ループの仮定を破っていることです。私があなたのコードをテストすると、例えばwhile()whileループでは、*動作しません。 –
情報とコードについてもう一度おねがいします。将来のプログラムでこれを実装する予定ですが、現在の問題では十分ではありません。あなたのコードと私の唯一の違いは、新しいものが開かれたときにプログラムのリストを更新するのに対し、mineはユーザーの要求でリストを返すことです。しかし、最初のリクエストから受け取ったリストは、新しいアプリが開かれても、後続のリクエストに変更を加えることはありません。 – sud0