2014-05-06 1 views
3

Прежде всего, голый со мной, потому что это мой первый вопрос, связанный с iOS для SO.Вызов NSURLConnection внутри dispatch_async и чтение didReceiveResponse в mainRunLoop в разработке iPhone

То, что я пытаюсь сделать, это получить ответ на следующий метод

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { } 

после вызова этого

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
[conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 
[conn start]; 

внутри

dispatch_async(); 

Но метод connection не звонит. Но когда я запускаю код NSURLConnection за пределами dispatch_async, он вызывает метод.

В чем причина этого и как его исправить? Это потому, что delegate относится к self, а self относится к фоновому потоку, но не к классу UIViewController?

+0

Какой поток вы используете при вызове 'dispatch_async' и в каком потоке вы хотите его отправить? – Levi

+0

, который отправляет очередь, вы используете в 'dispatch_async()'? –

+0

Когда я вызываю 'NSURLConnection', я внутри' dispatch_async() '. Кстати, вызывая '[self performSelectorOnMainThread: @selector (myBgWork) withObject: Nil waitUntilDone: NO];' this и помещать код 'NSURLConnection' внутри' myBgWork', дает мне ответ для 'didReceiveResponse'. Но теперь я смущаюсь, потому что снова чувствую, что мои фоновые работы снова обращаются к основной теме, и это замедлит мое приложение. Это так? – AnujAroshA

ответ

0

Поскольку вы создаете соединение, которое должно быть запланировано в цикле и начато позже, обязательно используйте значение initWithRequest с параметром startImmediately, установленным на NO. Прямо сейчас вы начинаете соединение дважды. И, что более важно, вы начинаете его, прежде чем планируете его в цикле основного запуска.

Чтобы исправить эту ситуацию, указать startImmediately в NO:

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

Сказав это, я не вижу никакой необходимости направить этот код в фоновом режиме очереди на всех (потому что initWithRequest работает асинхронно и не имеют заметное влияние на производительность приложения). Единственный раз, когда я использую описанный выше шаблон, - это когда я обматываю свои NSURLConnection запросы в некотором настраиваемом подклассе NSOperation (в этом случае приведенный выше шаблон очень полезен). Но в этом случае это не нужно.

+0

Спасибо за ответ. Я использовал 'dispatch_async()', потому что у меня тоже есть процесс архивирования файлов, который займет много времени. – AnujAroshA

+0

@AnujAroshA Затем вы можете отправить только этот процесс zipping в фоновый режим. Но нет смысла посылать начало соединения в фоновый режим, особенно если вы собираетесь развернуться и запланировать его в цикле основного запуска (что означает, что все методы делегата вызываются в основном потоке, хотя вы создаете экземпляр соединения из фоновой очереди). Даже если он не запускался в основном потоке, нет причин не делать этого. Просто отправьте этот медленный код на молнию в фоновый режим. – Rob

Смежные вопросы