2014-09-11 94 views
2

我有一个NSProgress对象树来监视涉及下载文件的数据处理。使用具有后台配置的NSURLSession完成下载。iOS 8 - NSProgress对象的fractionCompleted = 1.0由NSURLSessionDownloadTask在甚至恢复任务之前创建

当我开始这个过程时,最顶层的NSProgress对象报告意外的fractionCompleted数字。调试了这个问题(并将其隔离为“Hello World”应用程序), 我发现在调用上述方法之后,由于调用了[NSURLSession downloadTaskWithRequest:]并且它的fractionCompleted属性为1.0,所以创建了NSProgress对象。 由于这个NSProgress对象获得了我的NSProgress树的一部分,所以如果在树中偏移它上面的进度数字。

在这个示例应用程序中,我还开始了一个与下载并行的虚拟后台任务,该任务通过NSProgress对象报告进度。 我这样做的原因是,如果NSURLSession没有创建任何NSProgress对象(这是Apple声称的),NSProgress树中仍然至少有一个对象。

<NSProgress: 0x7ff8dae06b10> : Parent: 0x0/Fraction completed: 0.5000/Completed: 0 of 1 
    <_NSProgressGroup: 0x7ff8dae0f450> : Portion of parent: 1 Children: 1 
    <NSProgress: 0x7ff8dae0f880> : Parent: 0x7ff8dae06b10/Fraction completed: 0.5000/Completed: 0 of 100 
     <_NSProgressGroup: 0x7ff8dae0fec0> : Portion of parent: 100 Children: 2 
     <NSProgress: 0x7ff8dad74b90> : Parent: 0x7ff8dae0f880/Fraction completed: 1.0000/Completed: 1 of 1 
     <NSProgress: 0x7ff8daf036c0> : Parent: 0x7ff8dae0f880/Fraction completed: 0.0000/Completed: 0 of 100 

结果,报告进度会很奇怪:

已经启动下载和伪任务这里是NSProgress树的样子后立即记录的NSProgress树。

如果我注释掉调用开始下载([个体经营resumeDownload]),那么NSProgress树的样子:

<NSProgress: 0x7febca52ac90> : Parent: 0x0/Fraction completed: 0.0000/Completed: 0 of 1 
    <_NSProgressGroup: 0x7febca529e60> : Portion of parent: 1 Children: 1 
    <NSProgress: 0x7febca529ff0> : Parent: 0x7febca52ac90/Fraction completed: 0.0000/Completed: 0 of 100 
     <_NSProgressGroup: 0x7febca52ced0> : Portion of parent: 100 Children: 1 
     <NSProgress: 0x7febca52d780> : Parent: 0x7febca529ff0/Fraction completed: 0.0000/Completed: 0 of 100 

正如你可以看到有一个与fractionCompleted = 1.0,没有多余的NSProgress对象进度报告是好的。

现在我看不到NSProgress与fractionCompleted = 1.0是从哪里来的,如果它不是来自NSURLSession或下面的东西。 (Apple声明NSURLSession不会创建NSProgress对象。) 我只能在iOS 8上(即使使用GM版本)在iOS 7上看不到此行为。

请注意,我使用NSURLSession进行背景配置!使用默认配置时,问题不存在。

为什么该“意外的”NSProgress对象与fractionCompleted = 1.0一起出现? 我使用NSProgress API错误吗? 什么原因导致iOS 7和8上的行为非常不同?

的示例代码,请访问:https://s3-eu-west-1.amazonaws.com/pg.test/pubtest/NSProgress-20140830.zip

感谢提前任何帮助。

回答

3

我们遇到了上传进度的相同问题。正如你所说,看起来创建任务的调用是创建一个绑定到当前进度并立即完成的NSProgress对象。

uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; 

这引起了我们整体进展的问题。我们在我们的AFNetworking fork中创建了一个解决方法,以便通过一个块创建一个回调来创建NSProgress。 AFURLSessionManager中的方法已更新为具有进度创建块,而不是进度输出参数。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request 
            fromFile:(NSURL *)fileURL 
           progress:(NSProgress *(^)(int64_t totalUnitCount))progressCreationBlock 
          completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler 

这确保了只有在“进步”块中创建的进度对象被添加作为直接孩子目前的进展,而不是从创建会话的进展。然后块从被调用的实现看起来是这样的:

progress:^NSProgress *(int64_t totalUnitCount) { 
    [currentProgress becomeCurrentWithPendingUnitCount:1]; 

    NSProgress *progress = [NSProgress progressWithTotalUnitCount:totalUnitCount]; 

    [currentProgress resignCurrent]; 

    return progress; 
} 

https://github.com/cgreen-mmf/AFNetworking/commit/a0703a4f82a47e6c56c11245e4d88846ffbd0b28

我不清楚这是否是在运行iOS 8的一个bug,或者如果这是预期的行为。

相关问题