Я пытаюсь создать класс, который будет обрабатывать несколько загрузок одновременно (мне нужно загрузить много небольших файлов), и у меня проблемы с "исчезающими" соединениями.
У меня есть функция addDonwload, которая добавляет URL-адрес в список URL-адресов для загрузки и проверяет наличие свободного слота для загрузки. Если он есть, загрузка начинается немедленно. Когда одна из загрузок заканчивается, я выбираю первый список URL-адресов и начинаю новую загрузку.
Я использую NSURLConnection для скачивания, вот код
- (bool) TryDownload:(downloadInfo*)info
{
int index;
@synchronized(_asyncConnection)
{
index = [_asyncConnection indexOfObject:nullObject];
if(index != NSNotFound)
{
NSLog(@"downloading %@ at index %i", info.url, index);
activeInfo[index] = info;
NSURLRequest *request = [NSURLRequest requestWithURL:info.url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15];
[_asyncConnection replaceObjectAtIndex:index withObject:[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:TRUE]];
//[[_asyncConnection objectAtIndex:i] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
return true;
}
}
return false;
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
[self performSelectorOnMainThread:@selector(DownloadFinished:) withObject:connection waitUntilDone:false];
}
- (void)DownloadFinished:(id)connection
{
NSInteger index = NSNotFound;
@synchronized(_asyncConnection)
{
index = [_asyncConnection indexOfObject:(NSURLConnection*)connection];
}
[(id)activeInfo[index].delegate performSelectorInBackground:@selector(backgroundDownloadSucceededWithData:) withObject:_data[index]];
[_data[index] release];
[activeInfo[index].delegate release];
@synchronized(_asyncConnection)
{
[[_asyncConnection objectAtIndex:index] release];
[_asyncConnection replaceObjectAtIndex:index withObject:nullObject];
}
@synchronized(downloadQueue)
{
[downloadQueue removeObject:activeInfo[index]];
[self NextDownload];
}
}
- (void)NextDownload
{
NSLog(@"files remaining: %i", downloadQueue.count);
if(downloadQueue.count > 0)
{
if([self TryDownload:[downloadQueue objectAtIndex:0]])
{
[downloadQueue removeObjectAtIndex:0];
}
}
}
_asyncConnection - это мой массив слотов для загрузки (NSURLConnections)
downloadQueue - список URL для загрузки
Что происходит, в начале все работает нормально, но после нескольких загрузок мои соединения начинают исчезать. Загрузка начинается, но соединение: didReceiveResponse: никогда не вызывается. В консоли вывода есть одна вещь, которую я не понимаю, которая может немного помочь. Нормально есть что-то вроде
2010-01-24 21: 44: 17.504 appName [3057: 207]
до моих сообщений NSLog. Я думаю, что число в квадратных скобках - это какое-то приложение: идентификатор потока? все работает нормально, пока есть одно и то же число, но через некоторое время "NSLog (@" загрузка% @ по индексу% i ", info.url, index);" сообщения начинают отличаться от второго номера. И когда это происходит, я прекращаю получать любые обратные вызовы для этого URL-соединения.
Это сводило меня с ума, потому что у меня строгие сроки и я не могу найти проблему. У меня нет большого опыта работы с iphone dev и многопоточными приложениями. Я пробовал разные подходы, поэтому мой код немного запутан, но я надеюсь, что вы увидите, что я пытаюсь сделать здесь:)
Кстати, кто-нибудь из вас знает о существующем классе / lib, который я мог бы использовать, что также было бы полезно. Я хочу параллельные загрузки с возможностью o динамически добавлять новые файлы для загрузки (поэтому инициализация загрузчика в начале со всеми URL мне не нужна)