并发后台下载在iphone上 [英] concurrent background downloads on iphone

查看:101
本文介绍了并发后台下载在iphone上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建的类,将同时处理多个下载(我需要下载很多小文件),我有消失的连接的问题。

I am trying to create class that will handle multiple downloads at same time (I need to download a lot of small files) and I have problems with "disappearing" connections.

我有addDonwload函数,将url添加到要下载的URL列表,并检查是否有可用的免费下载插槽。如果有一个,它立即开始下载。当下载完成后,我选择第一个网址表单列表并开始下载。

I have function addDonwload that adds url to list of urls to download, and checks if there is free download slot available. If there is one it starts download immediately. When one of downloads finishes, I pick first url form list and start new download.

我使用NSURLConnection下载,下面是一些代码

I use NSURLConnection for downloading, here is some code

- (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列表

_asyncConnection is my array of download slots (NSURLConnections) downloadQueue is list of urls to download

会发生什么事,一开始一切正常,但在几次下载后,我的连接开始消失。下载开始但连接:didReceiveResponse:从未被调用。在输出控制台有一件事,我不明白我可能会帮助一点。 Normaly在我的NSLog消息之前有类似
2010-01-24 21:44:17.504 appName [3057:207]
。我猜在方括号中的数字是某种类型的应用程序:线程ID?一切正常,但有相同的数字,但一段时间后,NSLog(@下载%@在索引%i,info.url,索引);消息开始具有不同的第二数字。当这种情况发生时,我停止接收任何回调的url连接。

What happens is, at the beginning everything works ok, but after few downloads my connections start to disappear. Download starts but connection:didReceiveResponse: never gets called. There is one thing in output console that I don't understand I that might help a bit. Normaly there is something like 2010-01-24 21:44:17.504 appName[3057:207] before my NSLog messages. I guess that number in square brackets is some kind of app:thread id? everything works ok while there is same number, but after some time, "NSLog(@"downloading %@ at index %i", info.url, index);" messages starts having different that second number. And when that happens, I stop receiving any callbacks for that urlconnection.

这已经驱使我坚果,因为我有严格的截止日期,我找不到问题。我没有太多的iphone开发和多线程应用程序的经验。我一直在尝试不同的方法,所以我的代码是有点凌乱,但我希望你会看到我想在这里做:)

This has been driving me nuts as I have strict deadlines and I can't find problem. I don't have many experiences with iphone dev and multithreaded apps. I have been trying different approaches so my code is kinda messy, but I hope you will see what I am trying to do here :)

btw是你知道的任何人现有的类/ lib我可以使用,这将是有帮助的,以及。我需要并行下载能力o动态添加新文件下载(所以初始化下载程序在所有urls对我没有帮助)

btw is anyone of you know about existing class/lib I could use that would be helpful as well. I want parallel downloads with ability o dynamically add new files to download (so initializing downloader at the beginning with all urls is not helpful for me)

推荐答案

您有一系列严重的内存问题,并且此代码中存在线程同步问题。

You've got a bunch of serious memory issues, and thread synchronization issues in this code.

不是全部,我会问以下问题:你在某种背景线程上这样做?为什么? IIRC NSURLConnection已经在后台线程上进行下载,并在创建NSURLConnection的线程上调用您的委托(例如,您的主线程是理想的)。

Rather than go into them all, I'll ask the following question: You are doing this on a background thread of some kind? Why? IIRC NSURLConnection already does it's downloads on a background thread and calls your delegate on the thread that the NSURLConnection was created upon (e.g., your main thread ideally).

建议您退回,重新阅读NSURLConnection文档,然后删除您的背景线程代码和所有不必要的注入的复杂性。

Suggest you step back, re-read NSURLConnection documentation and then remove your background threading code and all the complexity you've injected into this unnecessarily.

进一步的建议:而不是试图保持两个数组中的并行定位(和上面的一些粗略代码相关),使一个数组和一个对象,包含NSURLConnection和对象表示结果。然后你可以在连接完成时释放连接实例var。和父对象(以及数据),当你完成数据。

Further Suggestion: Instead of trying to maintain parallel positioning in two arrays (and some sketchy code in the above relating to that), make one array and have an object that contains both the NSURLConnection AND the object representing the result. Then you can just release the connection instance var when the connection is done. And the parent object (and thus the data) when you are done with the data.

这篇关于并发后台下载在iphone上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆