Параллелизм и NSURLConnection - PullRequest
       6

Параллелизм и NSURLConnection

3 голосов
/ 02 ноября 2011

Недавно я исследовал и работал с NSURLConnection и параллелизмом. Кажется, есть несколько разных подходов, и те, которые я пробовал (очереди отправки и очереди операций), в конечном итоге все работали правильно.

Одна проблема, с которой я столкнулся при параллелизме и NSURLConnection, это то, что методы делегата не были вызваны. После некоторых исследований я обнаружил, что NSURLConnection должен быть либо запланирован в главном цикле выполнения, либо NSOperation должен выполняться в главном потоке. В первом случае я вызываю NSURLConnection так:

connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[connection start];

А в последнем случае так:

- (void)start
{
    if (![NSThread isMainThread])
    {
        [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
        return;
    }
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

Методы делегата обрабатывают все остальное, и оба, похоже, работают правильно. В случае, когда я использовал очередь отправки, я делал то же самое, что и в первом случае (запланируйте NSURLConnection в главном цикле выполнения).

Мой вопрос: в чем разница между этими двумя подходами? Или это на самом деле одно и то же, но просто другой способ их реализации?

Второй вопрос: зачем это нужно? Я также использую NSXMLParser внутри NSOperation, и для этого не требуется основной цикл выполнения или основной поток, он просто работает.

1 Ответ

4 голосов
/ 04 ноября 2011

Я думаю, что я понял это сам.Так как NSURLConnection и NSXMLParser являются асинхронными, им требуется цикл выполнения для сообщений делегата, когда они работают в фоновом режиме.Насколько я знаю, основной поток автоматически поддерживает выполнение цикла выполнения;основной цикл выполнения.Таким образом, оба решения для NSURLConnection, которые я опубликовал, убедятся, что основной цикл выполнения используется для асинхронной части, либо сообщив соединению использовать основной цикл выполнения для сообщений делегата, либо переместив всю операцию в основной поток,который также автоматически запланирует соединение в основном потоке.

Что я придумал сейчас, так это поддержание цикла выполнения в моих пользовательских классах NSOperation, поэтому мне больше не нужно выполнятьлюбое планирование или проверка потока.В конце метода (void)start я реализовал следующее:

// Keep running the run loop until all asynchronous operations are completed
while (![self isFinished]) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
...