あなたの問題はブロック(または辞書)とは何の関係もなく、あなたがどのように(ab)使用しているかと関係があります-runningApplications
。ドキュメントから:
NSRunningApplicationクラスのプロパティと同様に、このプロパティは、メインの実行ループが共通モードで実行されている場合にのみ変更されます。ポーリングの代わりに、Key-Value監視を使用して、この配列プロパティへの変更が通知されます。
この目的のために、以下は適切な動作を示しています。
#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];
}
}
これにはもう1つの優れた利点change
があります。興味がある場合は、辞書を調べて、通知をトリガーしたアプリケーションを特定します。これにより、以前の結果をキャッシュ/追跡する必要がなくなりますrunningApplications
。
編集:あなたのコメントに続いて、辞書に保存され、オブザーバーメソッドから呼び出されたブロック(私があなたのより大きなアプリで何かをしたと私が推測するデッドコードを取り除いた)でうまく機能するいくつかのコードがあります:
#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