2012-04-17 4 views
0

블록이 NSDictionary에 저장되어 있습니다.내 블록을 업데이트하려면 어떻게해야합니까?

void(^RunningApplications)(void) = ^{ 
     NSArray *runningApps = [[NSWorkspace sharedWorkspace] runningApplications]; 
     NSMutableArray *appNames = [[NSMutableArray alloc] initWithCapacity:[runningApps count]]; 
     for (NSRunningApplication *app in runningApps) 
      [appNames addObject:[app localizedName]]; 
     NSLog(@"%@", [[NSWorkspace sharedWorkspace] runningApplications]); 
    }; 

내가 현재 NSLog를 통해 실행중인 응용 프로그램을 볼이 블록에 처음으로 액세스이 그 블록 중 하나입니다. 그러나 다른 앱을 연 다음 블록을 다시 호출하면 새로 열린 앱이있는 새 목록이 아닌 원래 표시된 목록 만 볼 수 있습니다. 이 블록을 통해 업데이트 된 목록을 수신하려면 어떻게해야합니까?

답변

3

귀하의 문제는 블록 (또는 사전)과 관련이 있으며 -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 결과 캐싱/추적이 해제됩니다.

편집 : 귀하의 코멘트에 위로 다음, 여기 블록과 잘 작동 일부 코드가있어 사전에 저장 (난 당신의 큰 앱의 항목을했다 시작하더라도 죽은 코드의 제거)와 관찰자의 방법에서 호출 :

#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 
+0

정보를 보내 주셔서 감사합니다. 나는'runningApplications' 폴링이 이것을하는 적절한 방법이 아니라는 것을 이해합니다. 그러나 그것이 내가 업데이트 된리스트를 얻지 못하는 이유라고 생각하지 않습니다. 이전에이 폴링을 수행하고 업데이트 된 목록을 받았지만이 문제는 사전에서 블록에 액세스 할 때만 발생합니다. – sud0

+0

부작용없이 블록 사전에 구현 된 코드를 게시했습니다. 귀하의 문제는 폴링 방식이 실행 루프 가정을 어떤 식 으로든 깨뜨리고 있다는 것이 거의 확실합니다. 예를 들어, while() while 루프에서 코드를 테스트 할 때 확실히 * 작동하지 않습니다. –

+0

정보 및 코드를 다시 보내 주셔서 감사합니다. 나는 미래의 프로그램에서 이것을 구현할 것이지만 현재의 문제로는 충분하지 않다. 코드와 광산의 유일한 차이점은 새 프로그램이 열렸을 때 프로그램 목록을 업데이트하는 반면, 광산은 사용자의 요청에 따라 목록을 반환한다는 것입니다. 그러나 초기 요청에서받은 목록은 새 앱을 열어도 이후 요청이 변경되지 않습니다. – sud0

관련 문제