iOS 8-在恢复任务之前由NSURLSessionDownloadTask创建的fractionCompleted=1.0的NSProgress对象

iOS 8-在恢复任务之前由NSURLSessionDownloadTask创建的fractionCompleted=1.0的NSProgress对象,ios,objective-c,ios8,nsurlsession,nsprogress,Ios,Objective C,Ios8,Nsurlsession,Nsprogress,我有一个NSProgress对象树,用于监视涉及下载文件的数据处理。使用NSURLSession和后台配置完成下载 当我启动该过程时,最顶端的NSProgress对象报告意外的fractionCompleted图形。调试了该问题(并将其隔离到“Hello World”应用程序中), 我发现调用[NSURLSession downloadTaskWithRequest:]后创建了一个NSProgress对象,在调用上述方法之后,其fractionCompleted属性为1.0。 由于此NSProg

我有一个NSProgress对象树,用于监视涉及下载文件的数据处理。使用NSURLSession和后台配置完成下载

当我启动该过程时,最顶端的NSProgress对象报告意外的fractionCompleted图形。调试了该问题(并将其隔离到“Hello World”应用程序中), 我发现调用[NSURLSession downloadTaskWithRequest:]后创建了一个NSProgress对象,在调用上述方法之后,其fractionCompleted属性为1.0。 由于此NSProgress对象获取我的NSProgress树的一部分,因此if会偏移树中它上面的进度数字

在这个示例应用程序中,我还启动了一个与下载并行的虚拟后台任务,该任务通过NSProgress对象报告进度。 我这样做的原因是,如果NSURLSession不创建任何NSProgress对象(苹果公司声称),那么NSProgress树中至少还会有一个对象

在启动下载和虚拟任务后立即记录NSProgress树,这里是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: 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
:父项:0x0/已完成分数:0.5000/已完成:0/1
:父项部分:1子项:1
:父项:0x7ff8dae06b10/已完成分数:0.5000/已完成分数:0/100
:父项比例:100子项:2
:父项:0x7ff8dae0f880/已完成分数:1.0000/已完成:1/1
:父项:0x7ff8dae0f880/已完成分数:0.0000/已完成分数:0/100
因此,进度报告变得很奇怪

如果我注释掉启动下载的调用([self resumeDownload]),则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: 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
:父项:0x0/已完成分数:0.0000/已完成:0/1
:父项部分:1子项:1
:父项:0x7febca52ac90/已完成分数:0.0000/已完成分数:0/100
:父项比例:100子项:1
:父项:0x7febca529ff0/已完成分数:0.0000/已完成分数:0/100
如您所见,fractionCompleted=1.0时没有额外的NSProgress对象,并且进度报告正常

现在我看不出fractionCompleted=1.0的NSProgress是从哪里来的,如果它不是来自NSURLSession或下面的什么。(苹果表示NSURLSession不会创建NSProgress对象。) 我无法在iOS 7上看到这种行为,只能在iOS 8上看到(即使是GM版本)

请注意,我正在使用带后台配置的NSURLSession!对于默认配置,问题不存在

为什么“意外”Nprogress对象显示为fractionCompleted=1.0? 我是否使用了NSProgress API错误? 是什么导致iOS 7和iOS 8上出现截然不同的行为

此处提供了示例代码:


提前感谢您的帮助。

我们在上传进度时遇到了同样的问题。正如您所说,创建任务的调用似乎是在创建一个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”块中创建的progress对象作为直接子对象添加到当前进度中,而不是创建会话的进度。来自被调用方的块的实现将如下所示:

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

    NSProgress *progress = [NSProgress progressWithTotalUnitCount:totalUnitCount];

    [currentProgress resignCurrent];

    return progress;
} 

我不清楚这是否是iOS 8中的一个bug,或者这是否是预期的行为