2014-11-05 3 views
1

앱이 iOS 7에서 제대로 작동하지만 iOS 8 이상으로 전환하면 응용 프로그램이 작동하지 않습니다. 디버그 모드에서 앱의 NSThread detachNewThreadSelector 함수가 호출되어 사용자 액세스를 방지하기 위해 포 그라운드에 사용중인 상자를 만듭니다. 메인 스레드는 계속해서 데이터를 검색하기 위해 웹 서비스를 호출합니다. 데이터가 수신되면 다른 detachNewThreadSelector가 호출되어 첫 번째 스레드를 닫습니다.NSThread detachNewThreadSelector in iOS 8

iOS 8에서 디버그 모드로 단계별 실행하면 detachNewThreadSelector에 도달해도 아무런 변화가 없습니다. 첫 번째 스레드의 코드는 실행되지 않습니다. 메인 스레드는 계속 켜져 웹 서비스를 호출하여 데이터를 검색합니다. 데이터가 수신되면 두 번째 detachNewThreadSelector는 reach이지만 코드는 viewdidload 함수의 끝에 도달 할 때까지 실행되지 않습니다.

dismissActivityIndicator의 코드가 '보기 컨트롤러에서 종료 시도'오류를 생성하는 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION에서 실행됩니다. 그런 다음 __CFRunLoopDoSources0을 단계별로 실행 한 다음 __CFRunLoopRun에서 showActivityIndicator 코드를 실행합니다. 이렇게하면 dismissActivityIndicator가 이미 실행 된 이후 앱을 종료 할 수있는 바쁜 상자가 생성됩니다. 역순으로 viewdidload 함수의 끝에서 함수가 왜 호출되는지는 확실하지 않습니다.

이 프로젝트는 저에게 전달되었으므로 데이터가 소스에서 가져올 때까지 주 스레드를 차단하는 팝업보기를 생성하는 방법에 익숙하지 않습니다. iOS 8 문제를 해결하기 위해 어떤 일이 일어나고 있는지 신속하게 수정하거나 설명 할 필요가 있습니다.

-(void)callService{ 
    [NSThread detachNewThreadSelector: @selector(showActivityIndicator) toTarget:self withObject:NULL]; 
sleep(1); 

    //call web service 

    [NSThread detachNewThreadSelector: @selector(dismissActivityIndicator) toTarget:self withObject:NULL]; 
} 


-(void)showActivityIndicator{ 
    UISplitViewController *splitVC = [[self navigationController] splitViewController]; 
    UINavigationController *detailVC = [[splitVC viewControllers] objectAtIndex:1]; 

    activityIndicatorVC = [[ActivityIndicatorVC alloc] init]; 
    [activityIndicatorVC setModalTransitionStyle:UIModalTransitionStyleCoverVertical]; 
    [activityIndicatorVC setModalPresentationStyle:UIModalPresentationFormSheet]; 

    [detailVC presentViewController:activityIndicatorVC animated:NO completion: nil]; 
    CGRect r2 = CGRectMake(detailVC.view.bounds.size.width/2 - 80, 
         detailVC.view.bounds.size.height/2 - 150, 160, 160); 
    r2 = [detailVC.view convertRect:r2 toView:activityIndicatorVC.view.superview.superview]; 
    activityIndicatorVC.view.superview.frame = r2; 
} 

-(void)dismissActivityIndicator{ 
    UISplitViewController *splitVC = [[self navigationController] splitViewController]; 
    UINavigationController *detailVC = [[splitVC viewControllers] objectAtIndex:1]; 
    [detailVC dismissModalViewControllerAnimated:NO]; 
} 

답변

2

메인 스레드가 계속 데이터

나는 데이터 소스에서 가져올 때까지 메인 스레드를 차단하는보기를 팝업을 생성하는 방법에 익숙 해요를 검색하는 웹 서비스를 호출합니다.

메인 스레드에서 이러한 종류의 작업을 수행하지 마십시오! 이와 같은 문제는 메인 스레드를 UI 용으로 만 사용하고 다른 것을 기다려야하는 경우에는 결코 해결할 수 없습니다.

(아마도) 메인 스레드에서 sleep(1);을 수행하고 있는데, 이는 비슷한 이유로 불량합니다. 또한 적절한 디자인으로 sleep을 사용할 필요가 거의 없습니다. sleep의 사용은 스레딩을 이해하지 못하는 좋은 지표입니다.

지금에 대한 답변 (아마도)

내가 어려움을 당신이 자신의 스레드 showActivityIndicatordismissActivityIndicator을 분리하는 이유를 이해하는 데에. 메인 스레드 이외의 UI 작업은 모두 (스레드로부터 안전하지 않은) 정의되지 않은 동작 일뿐 아니라 일반적으로 나쁜 아이디어입니다.

두 번째로 서로 다른 스레드로 분리하여 둘 다 을 동시에 실행합니다.입니다. 분명히 이것은 이 아니며입니다. dismissActivityIndicator은 이전이 아닌 webservice 호출이 반환 된 후에 실행해야합니다. 코드에서 showActivityIndicatordismissActivityIndicator 사이의 실제 통화를 제거 했으므로 누가 실제로 여기에서 진행되고 있는지 알 수 있습니다. 나는 단순히 추측하고있다.

그것은 자체 스레드에서 실행되는 webservice 호출이어야합니다.그런 다음 주 스레드에서 완료 핸들러를 활용하여 해고해야하는 UI 요소를 제거합니다.

+0

이 기능은 앱이 작동하는 데 필요한 데이터를 호출하는 업데이트 기능입니다. 그것이 메인 스레드가 데이터가 수신 될 때까지 차단되는 이유입니다. –

+0

@vily 주 스레드를 차단할 좋은 이유가 아닙니다. 메인 스레드를 차단할 수있는 * 이유는 생각할 수 없습니다. –

+0

주요 기능은 많은 양의 데이터가 검색 될 때까지 showActivityIndicator와 메인 스레드를 동시에 실행하고 iOS 7에서 작동하는 앱을 사용 가능하게 만들기 위해 웹 서비스 호출이 완료된 후 dismissActivityIndicator가 첫 번째 스레드를 제거합니다. 함수는 초기화/업데이트 함수입니다. 작업이 시작되는 시점에 업데이트가 수행되지 않으면 데이터가 초기화되거나 올바른 데이터가 표시 될 때까지 앱이 작동하지 않습니다. 이 시점에서해야하는 이유는 앱이 인터넷에 연결되어 있지 않은 곳에서 사용되기 때문입니다. –

관련 문제