2016-05-31 8 views
1

, 는 내 프로그램 루프 차례로while (true) 문을 iOS 프로그래밍에서 유효한 접근 방법으로 사용 하시겠습니까? 대물 C에서

doInitialize() 
{ 
dispach_group_t loadDataGroup=dispatch_group_create(); 
dispatch_group_async(loadDataGroup,...get_global_queue(..),0),^{ 
    renewauth(); 
} 
dispatch_group_notify(loadDataGroup,...get_global_queue(..),0),^{ 
    //Do other tasks once renew session has completed... 
} 
} 
renewauth() 
{ 
RenewAuthTokenInProgress=true; 
startRenewThread(); 
**while (RenewAuthTokenInProgress);** 
} 

가 startRenewThread() 함수는 내부 dispatch_async 동작을 수행하는 동안 사용 기다려야 만들고있다. 그래서 renewAuth()를 기다려야합니다.

startRenewThread의 비동기 작업은 갱신이 완료되면 bool 변수를 업데이트합니다.

dispatch_groups 이외의 다른 방법을 사용하는 것이 더 좋습니까? 그리고 (참) 진술과 함께 다른 스레드를 기다리는 것이 좋습니까?

+0

바쁜 대기는 끔찍한 생각입니다. 어쨌든 끝날 때까지 차단하려는 경우 왜 백그라운드에서이 갱신 기능을 실행합니까? – Thilo

+0

그리고 비동기 경로로 가면'dispatch_groups'의 문제점은 무엇입니까? – Thilo

+1

RenewAuthTokenInProgress가 잠시 동안 true로 유지된다고 가정하면 iPhone이 뜨거워 질 것입니다. 코어 중 하나를 100 % 실행합니다. 또한 배터리를 평평하게합니다. – TJA

답변

6

마노 쿠마르

문제를 해결하기 위해 적절한 방법이 아니다. 이 방법에 대한 몇 가지 문제점은 다음과 같습니다.

  1. CPU에 변수를 정기적으로 검사해야하는 것은 아닙니다.

  2. 이것은 개발자가 코딩의 기본 기술과 언어와 함께 사용할 수있는 기능에 동등하지 않다는 것을 분명하게 보여줍니다.

  3. 어떤 이유로 든 변수가 절대로 변경되지 않으면 CPU는 while 루프에서 bool 값을 확인하는 것을 멈추지 않으며 동일한 스레드에서 추가 코드의 실행을 차단합니다.

다음은 올바른 접근 방법의 몇 가지 :

  1. 블록 또는 폐쇄를 다음 RenewAuthToken이 완료되면 블록의 사용은 비동기 적으로 코드를 실행합니다.

  2. 대리인 : 블록을 더 잘 이해하지 못하면 RenewAuthToken을 완료 한 후에 대리인을 사용하고 대리인을 트리거하십시오.

  3. 알림 : RenewAuthToken이 완료되었을 때 응답해야하는 클래스의 알림에 observer를 추가하고 asynctask에서 알림을 던져서 클래스가 코드를 catch하도록합니다.

  4. 잠금 : 응답하여 스레드의 실행을 제어하기보다는 사용 잠금을 제공까지 스레드의 실행을 차단하는 데 필요한 경우 동안 지적 루프

EDIT

out로 fogmeister 님의 의견에 의해

while (true) 루프를 사용하여 주 스레드를 너무 오래 차단하면 응용 프로그램은 실제로 는 링크에서 참조하시기 바랍니다

추락 한 가정합니다으로 아이폰 OS 감시에 의해 종료됩니다 understand iOS watchdog termination reasons

는 희망이 도움이 fogmeister에 의해 제공.

+3

또한 주목할만한 무엇인가. 'while (true)'루프로 메인 스레드를 너무 오래 차단하면 응용 프로그램이 실제로 iOS Watchdog에 의해 종료 될 것입니다. – Fogmeister

+0

@fogmeister : 빙고 :) 최대 투표 : –

+1

https://developer.apple.com/library/ios/technotes/tn2151/_index.html에서 '8badf00d' 검색을 원할 경우 추가 할 수있는 링크입니다. 워치 독 종료 이유를 표시합니다. – Fogmeister

1

난 당신이 그것의 필요 믿는 semaphore 같은 :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 

dispatch_semaphore_t sem = dispatch_semaphore_create(0); 
__block BOOL done = FALSE; 
while (true) { 

    [self someCompletionMethod completion:^(BOOL success) { 

     if(success) { // Stop condition 
      done = TRUE; 
     } 
     // do something 
     dispatch_semaphore_signal(sem); // This will let a new iteration 
    }]; 

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 

    if(done) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // Dispatch to main 
      NSLog(@"Done!"); 
      break; 
     }); 
    } 
} 

}); 

세마포어는 이제까지 - 그래서 - 겸손 에츠 허르 데이크 스트라에 의해 세계에 도입 된 구식 스레딩 개념이다. 세마포어는 운영 체제 기능이 복잡하기 때문에 복잡한 주제입니다.

당신은 세마포어에 대해 여기에 튜토리얼을보고 더 많은 링크를 그것을 확인할 수 있습니다 https://www.raywenderlich.com/63338/grand-central-dispatch-in-depth-part-2

나는이 당신을 도울 수 있기를 바랍니다. 부울 변수 변화까지 기다려야 while 루프를 사용

+0

세마포어는 종종 비동기 패턴을 처리하지 않는 게으름에 대한 알리바이입니다. – vadian

+1

불쾌감은 없지만, 종종 세마포어는 비동기 이벤트를 처리하는 훌륭한 방법입니다. 이 특정 질문에 대해서는 올바른 선택이 아닐 수도 있습니다. 그리고 고급 기술, 가능성이 OP를 넘어. – gnasher729

+0

불쾌감은 없습니다, 두 가지 의견을 모두 주셔서 감사합니다. 저는 이것이 꽤 의견이며, gnasher729에 동의하지만 저는 당신이 무슨 뜻인지 정말로 이해했습니다. –

0

당신이하는 일은 절대적으로 치명적입니다. UI가 정지되도록 실행중인 스레드 (아마도 메인 스레드)를 차단합니다. 어떤 이유로 든 배터리를 급속하게 비우고 전화를 데우는 100 %로드에서 코어 1 개를 실행합니다. 이렇게하면 아주 불행한 고객이나 매우 행복했던 전 고객을 얻을 수 있습니다.

다음과 같이 백그라운드에서 실행해야합니다. startRenewThread는 RenewAuthTokenInProgress = NO를 설정하고 새 토큰이 있는지 여부를 설정 한 다음 추가 작업을 트리거하는 동작을 트리거해야합니다.

이것은 iOS (및 Android에서 내가 아는 한 절대적으로 필수적인 프로그래밍 패턴입니다.