2012-03-06 25 views
-1

今日、私のアプリが時間通りに開始できなかった問題が発生しました。それ以前は、コードを呼び出す(http://blog.sallarp.com/iphone-ipad-get-user-agent-for-uiwebview/#more-1003から)メインスレッドで[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; 
} 

を、私はいくつかの操作をキューに入れられていた:それは私が使っていたいくつかのサードパーティのコードは以下のトリックを使用して、ユーザーエージェント文字列を取得しようとしていたが判明しますそれを+ [NSOperationQueue mainQueue]によって返されたキューに追加します。これらの操作は+ [NSData dataWithContentsOfURL:]を呼び出してバックグラウンドで実行されるように意図されています。

実行ループのメソッドが呼び出されると、キューに入れられた操作が実行され、メインスレッドがブロックされ、アプリケーションの起動が妨げられます。今はサードパーティのコードが実行されるまで操作を待ち行列に入れないようにすることで回避策を得ていますが、なぜこれが起こっているのか、そして将来どのように防止するのか分かっている人は、 。ありがとう!

+0

ドキュメントを少し見てみると、このモードで実行ループが使用可能な入力ソースを処理することを意味します。私は、キューに入れられた操作が重要だと思いますか?しかし、なぜこれを別のスレッドにディスパッチしないでしょうか? –

答えて

1

理由はかなり簡単です。メインキューの操作をキューに入れました。その後、誰か(このコード)がメインキューに操作を実行するように指示しました。あなたの操作は実行されました。これは、あなたが手動でメインrunloopを実行することはほとんどありません理由の一つです。それはあらゆる種類の奇妙なことを起こさせます。

これを防ぐには:メインrunloopを手動でポンプにかけないでください。ライブラリのバグを開いてください(NSAttributedString initWithHTML:...の中でメインrunloopを実行するAppleを含む)。

なぜ、呼び出し元コードがユーザエージェント文字列を望んでいるのかはっきりしません。一般的にあなたのビジネスではありませんが、それもかなり静的なので、他の方法で決定可能でなければなりません。目標を知らなければ、私はこれを何に置き換えるべきかはっきりしないが、このアプローチは良いことではない。

+0

ロブ、あなたの答えに感謝します。それは良い練習ではないことを知っていて良かった - 私は自分の前でそれを実際に見たことはなかった。これはNSOperationのメインスレッドの実行を引き起こすことは私には奇妙ですが、それはあなたが言及した奇妙な振る舞いだと思います。第三者コードがある限り、ユーザーエージェント文字列の必要性についてはコメントできません。 PS私はあなたの本が大好き! –

関連する問題