2013-10-10 1 views
0

파일 열기 대화 상자를 표시하는 OS X 용 기본 동적 라이브러리를 작성하려고합니다. 내 코드는 다음과 같이 보입니다 :MacOSX의 이상한 파일 대화 상자

년 - 대화는 결코 아주 두 번 같은 방법으로 (다른 초기 디렉토리, 레이아웃 모드를 초기화 :이 기본적으로 작동하는 동안 이제

NSOpenPanel * dlg = [NSOpenPanel openPanel]; 
...//setting title and other properties for dlg 

dispatch_group_t group = dispatch_group_create(); 
dispatch_group_async(group, dispatch_get_main_queue(),^
{ 
    resButton = [dlg runModal]; 
}); 
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 
if (resButton == NSFileHandlingPanelOKButton)//resButton is global 
{...} 

을, 모든 조금 떨어져입니다. ..).

- 처음 디렉토리는 다른 디렉토리와 처음 디렉토리를 다시 선택할 때까지는 비어있는 것으로 표시되는 경우가 있습니다.

- '마우스 오른쪽 버튼 클릭'메뉴가 표시되지 않습니다.

- 돌아 오는 바운스 백 효과가 작동하지 않습니다 (!!!). 모든 것이 사라질 때까지 무한정 아래쪽으로 스크롤 할 수 있습니다.

- 큰 아이콘 모드로 볼 때 이미지가 적절한 미리보기를 갖지만 열 모드에서는 미리보기가 작동하지 않습니다 (로드 아이콘이 영원히 바뀝니다).

실행 중이 지 않은 전체 업데이트 스레드가있는 것처럼 보입니다. 이것은 아마도 lib가 호출되는 이상한 맥락, 즉 JNA를 사용하는 자바 프로그램으로부터 연결될 것입니다. 그러나 나는 어쩌면 누군가 또는 무언가 "단지 [시스템 startUpdateTask]을 호출"같은 일을 해결할 수있는 약간의 트릭 알고 바라고 있어요 :) 어떤 도움

감사

+0

모든 'dispatch_' 코드를 블록'resButton = [dlg runModal];의 본문으로 대체하면 어떻게됩니까? 'runModal'은 결국 동기식 호출입니다 ... – CRD

+0

@CRD 디스패치 물건이 없으면 예외가 발생하여 "스레드 0"을 사용하지 않는다는 appkit 예외가 발생합니다. – schmop

+0

메인 스레드에서 호출해야합니다 ... 왜 디스패치 대기열을 사용해야하는지 잘 모르겠습니다. performSelectorOnMainThread 사용 –

답변

1

(

코멘트 응답 : 후

시도해 볼만한 것 (시나리오를 테스트 할 수 없습니다). NSOpenPanel/NSSavePanel은 샌드 박스가 도입 된 이래로 매우 섬세한 클래스이며주의해서 처리해야합니다.

발견 한대로 모든 UI 작업이 주 스레드에서 수행되어야합니다. 그러나 대신 dispatch_* 기능을 사용하여 시도 performSelectorOnMainThread 동기 : 여부, 문제를 해결할 수 있습니다

NSOpenPanel * dlg = [NSOpenPanel openPanel]; 
... //setting title and other properties for dlg 

resButton = [dlg performSelectorOnMainThread:@selector(runModal) 
            withObject:nil 
           waitUntilDone:YES]; 

if (resButton == NSFileHandlingPanelOKButton) //resButton is global 
{...} 

...

부록 올바르게 지적으로,

내 나쁜 performSelectorOnMainThread은 값을 반환하지 않습니다. 대신 다음을 할 수 있습니다 :

resButton을 클래스에 인스턴스 변수로 추가하십시오.

- (void) myRunModal:(NSOpenPanel *)dlg 
{ 
    resButton = [dlg runModal]; 
} 

변경에 코드 : 비슷한

[self performSelectorOnMainThread:@selector(myRunModal:) 
         withObject:dlg 
        waitUntilDone:YES]; 

또는 뭔가

메소드를 추가합니다.

+0

불행히도 performSelectorOnMainThread의 반환 유형은 void이며 예제에서와 같이 resButton = [...]을 사용할 수 없습니다. – schmop

+0

resButton을 지정하지 않고 테스트 했으므로 (사용자가 확인 또는 취소 할 수 있는지 여부는 알 수 없음) ... 작동합니다! 즉, 모든 것이 정상적으로 작동합니다. 콜백을 사용하여 Ok와 취소 사이를 구별 할 수 있다고 생각합니다. 고마워! – schmop

+0

@schmop - 죄송합니다. 답변에 직접 코드를 작성해서는 안됩니다. addenudum 추가 중 ... – CRD