Вызов - [NSRunLoop runMode: beforeDate:] в главном потоке вызывает выполнение операций NSO в очереди в основном потоке - PullRequest
0 голосов
/ 06 марта 2012

Я столкнулся с проблемой сегодня, когда мое приложение не запускалось вовремя.Оказывается, какой-то сторонний код, который я использовал, пытался получить строку пользовательского агента, используя приведенный ниже прием:

-(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:].

После того, как методв цикле выполнения вызывается, он выполняет мою операцию с очередями, блокируя основной поток и предотвращая запуск приложения. Сейчас я нашел обходной путь, убедившись, что не ставит в очередь какие-либо операции до тех пор, пока не выполнится сторонний код, ноесли кто-нибудь знает, почему это происходит, и как это предотвратить в будущем, я бы хотел это услышать. Спасибо!

1 Ответ

1 голос
/ 07 марта 2012

Почему это довольно просто.Вы поставили в очередь операции в главной очереди.Затем кто-то (этот код) велел основной очереди запускать операции.Ваши операции закончились.Это одна из причин, по которой вам никогда не следует запускать основной цикл запуска вручную.Это приводит к всевозможным странным вещам.

Что касается того, как предотвратить это: не качайте основной цикл запуска вручную и не открывайте ошибки в библиотеках, которые это делают (в том числе в Apple для запуска основного цикла запуска всередина NSAttributedString initWithHTML:...).

Я не понимаю, почему вызывающему коду нужна строка user-agent.Как правило, это не ваш бизнес, но он также довольно статичен, поэтому должен быть определен другими способами (не в последнюю очередь это просто жесткое кодирование ответа).Не зная цели, я не уверен, что заменить это, но этот подход не является хорошим.

...