2012-01-16 6 views
0

연결을 기다리는 응용 프로그램이 있습니다. 응용 프로그램이 대기하는 동안 AlertView의 취소 버튼을 클릭하거나 프로그래밍 방식으로 언젠가는 종료해야하는 AlertView를 사용자에게 표시해야합니다.UIAlertView는 주 스레드가 IOS에서 차단되었을 때 스레드에서 닫습니다.

메인 스레드는 클라이언트가 연결되기를 기다리고 있습니다. 다른 스레드에서 대화 상자의 시간을 업데이트하는 AlertView를 생성하고 보여줍니다. 쓰레드에는 AlertView의 텍스트를 업데이트하는 NSRunLoop이 있습니다.

AlertView가 터치 이벤트를 수신하지 않고 프로그래밍 방식으로 해제되지 않는 경우를 제외하고는 모두 잘 작동합니다. 아무도 내가 여기서 잘못하고있는 것에 대해 약간의 빛을 낼 수 있을까요?

다음은 샘플 코드입니다.

funcA() { 

    [NSThread detachNewThreadSelector:@selector(createDialog) toTarget:self withObject:nil]; 

    [NSThread detachNewThreadSelector:@selector(updateDialog) toTarget:self withObject:nil]; 

    .. 

    .. 

    BlockingWait(); 

    .. 

    .. 

} 

- (void) createDialog { 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    alert = [[UIAlertView alloc] initWithTitle:@"Wait" message:@"\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; 

    ... 

    label = [[UILabel alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 225.0f, 90.f)]; 

    [alert show]; 

    [alert release]; 

    [pool drain]; 

} 

- (void) upDateDialog { 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSRunLoop *loop = [NSRunLoop currentRunLoop]; 

    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateText) userInfo:nil repeats:YES]; 

    [loop run]; 

    [pool drain]; 
} 

- (void) updateText { 

    label.text = " Wait for" + n + "secs"; 

    n--; 

    if (n == 0) 
     [alert dismissWithClickedButtonIndex:0 animated:YES]; // Doesn't work 
} 


- (void) alertView: (UIAlertView *) alert clickedButtonAtIndex:(NSInteger) buttonIndex { 
// Never Gets called 
    NSLog(@"Alert is dissmissed with button index %d", buttonIndex); 

    if (buttonIndex == 0) { 

     [timer invalidate]; 
    } 
} 

답변

2

코드를 읽지도 않았는데, 실제로 헤드 라인은 이미 아키텍처에서 실제로 작동해야한다는 것을 보여줍니다. UIKit을 해킹하려고 할 수 있지만 UI 스레드 만 관리하도록 설계되었습니다. 따라서 스레드에서 차단 호출을 이동하고 주 스레드에서 UIAlertView를 관리하십시오.

0

메인 스레드를 차단하지 마십시오. 절대로. UIAlertView을 비동기 적으로 크래킹하고 다른 작업을 수행하는 동안 ivar로 유지 한 다음 필요에 따라 업데이트하십시오. 이 작업을 위해 스레드 또는 블로킹이 필요하지는 않습니다. NSURLConnection을 비동기 적으로 사용하면 차단하지 않고 연결을 관리 할 수 ​​있습니다.

+0

나는 더 나은 아키텍처가 주 스레드에 UI를 가지고 있다는 것을 알고 있지만 그것에 대한 많은 설계 변경을해야합니다. 보조 스레드에서 터치 이벤트를 수신 할 수 있습니까? – Rajat

+0

아니요. UIKit은 스레드로부터 안전하지 않으며 주 스레드가 아닌 다른 스레드에서도 실행할 수 있습니다. 이 사실을 해결할 수는 없습니다. "일종의 일종"을 얻더라도 모든 플랫폼 및 OS 버전에서 다를 수있는 중요한 경쟁 조건에 직면하게됩니다 (OSKit 경합 조건은 OS 버전간에 변경됩니다). –