2

백그라운드 작업이 완료되면 iPhone 앱 IOS 프로그램의 기본 UI 스레드에 표시를 얻으려면 어떻게해야합니까?백그라운드 작업이 완료되면 주 UI 스레드에 표시하는 방법은 무엇입니까? (performSelectorInBackground)

배경 내가 How to add a UIActivityIndicator to a splash screen in a iphone application?

  • 에서 설정에 개념 당 로딩 표시기를 시도하고있다가 AppDelete 사용 "performSelectorInBackground"에 가고 있었다

    • 모델 데이터를로드 할 수
    • 그래서 저는 필요 RootViewController에서 데이터가 백그라운드에서로드가 완료되면 (a) 데이터로 tableview를 업데이트하고 (b) 모든 활동 표시기를 제거 할 수있는 방법을 알려주는 것입니다.
    • 여기에 작업을 수행하는 방법을 추측하고 있습니다. 나는 다음으로 S :
      • 앱 위임 didFinishLaunchingWithOptions의 배경에 RootViewController를
      • AppDelegate에 부하를 모델 데이터 로딩을 넘기 최대 즉시 설치 데이터가 배경에로드되면
      • , 어떻게 든 표시하는 작업 표시기를 이 다시 RootViewController (? 이 질문에 대한 이유) 완료되었습니다
      • 두 번째 질문은 아마도 백그라운드 작업이 완료된 것을 초기화하지 않을 때입니다. RootviewController가 활동 표시기를 비활성화하기 전에 UI가 설정을 얻었는지 확인하는 방법은 무엇입니까?
  • 답변

    3

    당신과 같이 -performSelectorOnMainThread:withObject:waithUntilDone:를 사용하여 배경 선택에서 메인 스레드로 다시 호출 할 수 있습니다

    - (void)loadModel 
    { 
        // Load the model in the background 
        Model *aModel = /* load from some source */; 
    
        [self setModel:aModel]; 
        [self performSelectorOnMainThread:@selector(finishedLoadingModel) withObject:nil waitUntilDone:YES]; 
    } 
    
    - (void)finishedLoadingModel 
    { 
        // Notify your view controller that the model has been loaded 
        [[self controller] modelLoaded:[self model]]; 
    } 
    

    업데이트 : 이 작업을 수행하는 경우에도 안전한 방법은 메인 스레드에서 실행하고 있는지 확인하기 위해 -finishedLoadingModel에 확인하는 것입니다 :

    당신이 백그라운드에서로드가 완료되면
    - (void)finishedLoadingModel 
    { 
        if (![NSThread isMainThread]) { 
         [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:YES]; 
        } 
        // Notify your view controller that the model has been loaded 
        [[self controller] modelLoaded:[self model]]; 
    } 
    
    +0

    감사합니다. "modelLoaded"가 호출 될 때 주 스레드가 활동 표시기와 함께 UI를 표시 할만큼 충분히 멀리 있는지 확인하는 방법에 대한 의견이 있으십니까? 즉, 아직 설정/표시되지 않았을 때 activtyIndicator를 숨기려고하는 "modelLoaded"메소드의 잠재적 문제를 처리하는 방법은 무엇입니까? – Greg

    +0

    주 스레드에서 활동 표시기를 표시하고 숨기 만하면 괜찮을 것입니다. 따라야 할 기본 워크 플로는 다음과 같습니다. 1) 표시 활동 표시기. 2) 배경 스레드를 시작; 3) 작업이 끝나고 메인 스레드로 돌아 왔으면 활동 표시기를 숨 깁니다. –

    +0

    ok - 내 주문을 다시해야 할 수도 있습니다 - 백그라운드 모델로드가 AppDelegate : didFinishLaunchingWithOptions에서 시작되었습니다. rootViewController의 viewDidLoad – Greg

    1

    , 당신의 배경 스레드에서 다음을 호출

    [self performSelectorOnMainThread:@selector(backgroundLoadingDidFinish:) withObject:nil waitUntilDone:NO]; 
    

    그리고 나서 -(void)backgroundLoadingDidFinish:(id)sender을 RootViewController에 구현하십시오. 필요한 경우 위의 방법 (withObject: 부분)으로 데이터를 다시 전달할 수 있습니다.

    +0

    StuDev에게 감사드립니다. "modelLoaded"가 호출 될 때 주 스레드가 활동 표시기와 함께 UI를 표시 할만큼 충분히 멀리 있는지 확인하는 방법을 다시 묻습니다. 즉, 아직 설정/표시되지 않았을 때 activtyIndicator를 숨기려고하는 "modelLoaded"메소드의 잠재적 문제를 처리하는 방법은 무엇입니까? – Greg

    +0

    @ 그렉 : 나는 그 대답에 대한 카메론의 코멘트가 당신이 요구하는 것을 다루고 있다고 생각합니다. 먼저 지표를 적재하고 배경에서 데이터를로드하기 시작하십시오. 어쨌든, 당신은 항상 그것을 숨기기 전에 활동 지시계의 존재를 검사 할 수 있고,'nil'에'removeFromSuperview'를 호출하는 것을 기억할 수 있습니다 (즉, 활동 지시계가 아직 존재하지 않는다면). 우연히 있다. – Stuart

    +0

    StuDev에게 감사드립니다 - "removeFromSuperview on nil이 유효합니다"에 대한 좋은 지적 – Greg

    관련 문제