Асинхронный NSURLConnection в отдельном потоке не может вызвать методы делегата

Я запускаю NSURLConnection в отдельном потоке (я знаю, что он асинхронный и работает при запуске в основном потоке), но он не вызывает вызовов делегата, даже когда я передаю родительский поток в качестве делегата. Кто-нибудь знает как это сделать?

Код:

-(void)startConnectionWithUrlPath:(NSString*)URLpath {

//initiates the download connection - setup
NSURL *myURL = [[NSURL alloc] initWithString:URLpath];

myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
[myURL release];


//initiates the download connection on a seperate thread
[NSThread detachNewThreadSelector:@selector(startDownloading:) toTarget:self withObject:self];

}


-(void)startDownloading:(id)parentThread {

 NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

 [NSURLConnection connectionWithRequest:myURLRequest delegate:parentThread];
 //The delegate methods are setup in the rest of the class but they are never getting called...

 [pool drain];
}

ИЗМЕНИТЬ *

Причина, по которой мне нужно запускать NSURLConnection в отдельном потоке, заключается в том, что я загружаю что-то в своем приложении для iPhone, и загрузка отменяется, когда пользователь блокирует экран (он продолжает работать нормально, если пользователь просто нажимает кнопку домой, а приложение переходит в фоновый режим) ). Я понимаю, что это связано с тем, что я запускаю соединение асинхронно в основном потоке, а не в отдельном.

Я также пробовал этот код (НЕ в отдельном потоке) при запуске NSURLConnection:

  NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:myURLRequest delegate:self startImmediately:NO];
   [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
   [connection start];
   [connection release];

Но у меня такая же проблема с отменой загрузки при блокировке экрана.

* ОБНОВЛЕНИЕ

Чтобы добавить к ответу Томаса ниже (обратите внимание, что ответ Джеймса Вебстера также верен в отношении выхода из потока), документы Apple объясняют: «Приостановленное состояние - приложение находится в фоновом режиме, но не выполняет код. Система перемещает приложения в это состояние автоматически и не уведомляет их перед этим. В приостановленном состоянии приложение остается в памяти, но не выполняет никакого кода ».

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

Поэтому я приостанавливаю (сохраняю определенную информацию и отменяю NSURLConnection) все загрузки, когда приложение переходит в фоновый режим, и возобновляю их с заголовком HTTP Range, когда оно снова становится активным. Это обходной путь, который хорош, но не идеален, поскольку загрузка не происходит в фоновом режиме, что отрицательно влияет на работу пользователя ... облом.


person Zigglzworth    schedule 29.02.2012    source источник
comment
методы, которые вы используете для запроса NSURLConnection, сами по себе являются асинхронными, поэтому, даже если вы не отключите новый поток, это будет многопоточная операция.   -  person Ravin    schedule 29.02.2012
comment
Отредактированный вопрос, чтобы лучше объяснить мою проблему.   -  person Zigglzworth    schedule 29.02.2012


Ответы (2)


Поскольку ваш NSURLConnection является асинхронным, конец вашего метода -startDownloading достигается немедленно, и поток завершается.

Вы действительно должны запланировать свое соединение в основном цикле выполнения (или использовать GCD).

Еще одна проблема - блокировка устройства. Когда устройство заблокировано, ваше приложение приостанавливается для экономии заряда батареи. Вероятно, вы можете попросить дополнительное время при приостановке, чтобы завершить загрузку.

person Thomas Deniau    schedule 29.02.2012
comment
Спасибо. Я обновил свой вопрос, основываясь на вашем ответе. Похоже, что просить больше времени нужно только для приложений, работающих в фоновом режиме, а не для приостановленных. - person Zigglzworth; 29.02.2012

Я думаю, ваша проблема может заключаться в том, что NSURLConnection был освобожден, как только вы выйдете из сообщения startDownloading: (или, точнее, когда ваш пул автозапуска истощен)

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

Попробуйте это и посмотрите, работает ли оно так, как вы ожидаете (т.е. ваше приложение не приостанавливается, пока ваше соединение занято)

-(void)startConnectionWithUrlPath:(NSString*)URLpath {

    //initiates the download connection - setup
    NSURL *myURL = [[NSURL alloc] initWithString:URLpath];

    myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
    [myURL release];

    [NSURLConnection connectionWithRequest:myURLRequest delegate:self];
}
person James Webster    schedule 29.02.2012
comment
Отредактированный вопрос, чтобы лучше объяснить мою проблему. - person Zigglzworth; 29.02.2012
comment
Хорошо, ваше редактирование имеет смысл. Тогда обратите внимание на первую часть моего ответа. Кажется, ваш NSURLConnection был отключен почти сразу. - person James Webster; 29.02.2012
comment
Этот ответ упоминается как правильный в моем обновлении вопроса. - person Zigglzworth; 29.02.2012