4

我知道我可以dataTaskWithURL:completionHandler:用来获取 completionHandler 块中的数据,但这会阻止委托方法触发,我需要触发该didReceiveData:方法,因为这是我配置进度指示器的方式。

一旦完成,我完全不知道如何获取下载的数据。什么是完成块的委托方法等价物?didCompleteWithError似乎没有返回任何NSData.

我不必手动将数据拼凑在一起didReceiveData,对吗?当 completionHandler 把它交给你时,这似乎真的很糟糕。如果不是因为我可以一次下载 50 多个东西,我不介意这样做,所以跟踪所有部分数据似乎很痛苦。我应该切换到NSURLSessionDownloadTask吗?

4

1 回答 1

6

是的,您必须手动将数据拼凑在一起(或者如果它真的很大并且您不希望它占用内存,您可以将其流式传输到文件中)。

因此,didReceiveData方法将在数据进入时返回您的数据。因此,您应该实例化一个NSMutableData(例如, in didReceiveResponse),didReceiveData它将在数据进入时附加数据。当didCompleteWithError被调用时,假设错误是nil,您可以确信您NSMutableData现在包含收到的所有数据。正如您所指出的,挑战在于跟踪所有 50 多次下载,因此我维护了一个以任务标识符为键的字典,以跟踪将数据附加到哪个字典。(就个人而言,我认为这是一个设计缺陷,它NSURLSession在会话级别实现任务、下载和上传委托,而不是让我们为每个任务实例化单独的任务委托对象。但我们被我们所拥有的东西所困扰。)

如果您只是下载数据,这NSURLSessionDownloadTask是一个很好的选择(并且在内存使用方面比仅附加到NSMutableData实例更有效),并且您可以想象如果您愿意也可以使用后台会话(您不能使用一NSURLSessionDataTask)。

最后,如果您真的要进行 50 次以上的下载,您可能需要考虑将下载任务包装在NSOperation子类中,这样您就可以限制并发运行的数量,而不会冒任何超时的风险。

于 2014-02-21T04:03:17.940 回答