2012-03-06 4 views
-1

오늘 내 앱이 제 시간에 시작하지 못하는 문제가 발생했습니다.메인 스레드에서 [NSRunLoop runMode : beforeDate :]를 호출하면 대기중인 NSOperations가 메인 스레드에서 실행됩니다.

-(NSString*)userAgentString 
{ 
    webView = [[UIWebView alloc] init]; 
    webView.delegate = self; 
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"www.google.com"]]]; 

    // Wait for the web view to load our bogus request and give us the secret user agent. 
    while (self.userAgent == nil) 
    { 
     // This executes another run loop. 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
    } 

    return self.userAgent; 
} 

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 
    self.userAgent = [request valueForHTTPHeaderField:@"User-Agent"]; 

    // Return no, we don't care about executing an actual request. 
    return NO; 
} 

(http://blog.sallarp.com/iphone-ipad-get-user-agent-for-uiwebview/#more-1003에서) 이전에 그 코드를 호출에, 나는 대기했던 일부 작업을 : 그것은 내가 아래의 트릭을 사용하여 사용자 에이전트 문자열을 얻으려고 사용하던 일부 타사 코드를 밝혀 + [NSOperationQueue mainQueue]에 의해 반환 된 대기열에 추가하여. 이러한 작업은 + [NSData dataWithContentsOfURL :]을 (를) 호출 할 때 백그라운드에서 실행됩니다.

실행 루프의 메서드가 호출되면 대기중인 작업을 실행하여 주 스레드를 차단하고 응용 프로그램이 시작되지 않도록합니다. 지금 당장 타사 코드가 실행될 때까지 작업을 대기열에 넣지 않도록하여 해결 방법을 얻었습니다. 그러나이 문제가 왜 발생하는지, 그리고 앞으로이를 방지하는 방법을 알고 있다면 누구나 듣고 싶습니다. . 감사!

+0

문서를 조금 보시면이 모드에서 사용할 수있는 입력 소스를 처리하는 루프가 있음을 의미합니다. 대기중인 작업이 중요하다고 생각합니까? 그런데 왜 다른 스레드로 이것을 보내지 않을까요? –

답변

1

왜 그리 간단합니까? 기본 대기열에서 작업을 대기 중입니다. 그런 다음 누군가 (이 코드)가 메인 큐에 작업을 실행하라고 지시했습니다. 당신의 작전이 도망갔습니다. 이것이 메인 런 루프를 수동으로 실행하지 않아야하는 이유 중 하나입니다. 그것은 모든 종류의 이상한 일이 일어나게합니다.

방지 방법 : 메인 runloop을 수동으로 펌핑하지 말고, NSAttributedString initWithHTML:...의 중간에있는 메인 runloop을 실행하는 Apple을 포함한 라이브러리에 대한 버그를 엽니 다.

호출 코드가 사용자 에이전트 문자열을 원하는 이유가 명확하지 않습니다. 일반적으로 귀하의 비즈니스는 아니지만 상당히 정적이기 때문에 다른 방법으로 결정할 수 있어야합니다 (그 중 가장 적은 것은 대답을 하드 코딩하는 것이 아닙니다). 목표를 알지 못하면 무엇을 대체 할 지 확신 할 수 없지만이 접근법은 좋지 않습니다.

+0

롭, 대답 해줘서 고마워. 좋은 연습이 아니라는 것을 알기가 쉽습니다. 직접 본적이 없습니다. NSOperation의 메인 쓰레드 실행을 일으키는 것은 이상한 일입니다.하지만 그것은 당신이 언급 한 이상한 행동입니다. :) 제 3 자 코드에 관한 한, 사용자 에이전트 문자열에 대한 필요성에 대해서는 언급 할 수 없습니다. 추신 : 나는 당신의 책을 좋아합니다! –

관련 문제