Async NSURLConnection, Concurrent NSOperation, когда использовать NSRunLoop? - PullRequest
4 голосов
/ 30 апреля 2011

Я пытаюсь запустить NSURLConnection async во вторичном потоке (цель - iOS4), для этого я создал параллельную NSOperation, я думаю, что я почти там, но мне не ясно следующее:

1) в iOS4 NSOperationQueue addOperation запускает операцию в новом потоке из-за использования GCD на основе Технические вопросы и ответы QA1712 , однако, мои тесты (симулятор и iPad) показывают, что start () всегда вызывается в главном потоке, любая идея, нужна ли здесь проверка: если в главном потоке появляется новый?

2) если запуск был фактически вызван во вторичном потоке с помощью addOperation (), то я мог бы запустить асинхронное NSURLConnection, запланировав текущий NSRunLoop:

[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];

как пример LinkedImageFetcher здесь , и мне не нужно было бы зацикливаться, пока не завершится с:

do {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);

3) предполагая, что моя пользовательская NSOperation start () вызывается в главном потоке, а 2) верна, и я запускаю новый поток в start () для вызова моего пользовательского метода main () с помощью:

[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];

В моем main () мне нужно запустить цикл выполнения текущего потока:

do {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);

Это единственный экземпляр, в котором мне удалось запустить NSURLConnection в параллельной NSOperation, но я не уверен, что мне действительно нужно запустить RunLoop, если поток был предоставлен GCD как состояние технических примечаний, могу ли я следуйте логике в 2) или мне все равно придется запускать цикл выполнения потока? Как я могу проверить поток, предоставленный GCD?

Большое спасибо за любое разъяснение

Ответы [ 2 ]

9 голосов
/ 04 июня 2011

Ну, в конце концов я решил это, поэтому подумал, что люди могут быть заинтересованы в деталях:

1) start () был вызван в главном потоке, потому что я использовал [NSOperationQueue mainQueue] вместо создания новой очереди с [[NSOperationQueue allc] init]. Однако проверка в NSOperation start () на предмет того, был ли текущий поток mainThread или нет, а затем вызов main () непосредственно оттуда или путем создания нового потока (в случае, если мы были на mainThread), не повредил.

2) Я понял, что LinkedImageFetcher слишком сложен для понимания циклов выполнения и потоков, и излишне так, потому что тема не так сложна. Все, что необходимо в методе start () - это поддерживать цикл выполнения вторичного потока до тех пор, пока мы не закончим (isCompleted), весь цикл выполнения для NSURLConnection прослушивает входные данные из соединения и запускает обратные вызовы (didreceivereponse, Didreceivedata и т. д.).

3) да, запуск цикла выполнения необходим для получения обратных вызовов соединения в том же (вторичном в данном случае) потоке.

Подробнее см. Выполнить циклы в Руководстве по программированию потоков.

0 голосов
/ 30 апреля 2011

Я не уверен, что понимаю, что вы пытаетесь достичь: NSURLConnection API имеет встроенный асинхронный метод initWithRequest: Delegate:

Есть ли какая-либо конкретная причина, почему вы не можете использовать это?

...