Objective c 如何知道NSURLSessionDataTasks的for循环何时完成

Objective c 如何知道NSURLSessionDataTasks的for循环何时完成,objective-c,loops,ios7,objective-c-blocks,nsurlsession,Objective C,Loops,Ios7,Objective C Blocks,Nsurlsession,我正在调用一个方法,该方法将枚举一个数组,创建一个NSURL,并调用一个返回JSON的NSURLSessionDataTask。循环通常运行10次左右,但根据日期的不同而有所不同 我需要等待for循环和所有NSURLSessionDataTasks完成,然后才能开始处理数据 我很难弄清楚所有的工作什么时候完成。有谁能推荐一些方法或逻辑来知道整个方法何时完成(对于循环和数据任务) }看看你的例子,大致如下: create group for (url in urls) enter g

我正在调用一个方法,该方法将枚举一个数组,创建一个NSURL,并调用一个返回JSON的NSURLSessionDataTask。循环通常运行10次左右,但根据日期的不同而有所不同

我需要等待for循环和所有NSURLSessionDataTasks完成,然后才能开始处理数据

我很难弄清楚所有的工作什么时候完成。有谁能推荐一些方法或逻辑来知道整个方法何时完成(对于循环和数据任务)

}

看看你的例子,大致如下:

 create group
 for (url in urls)
     enter group
     start_async_task
         when complete leave group

 wait on group to finish or supply a block to be run when completed

有很多选择。基本问题是这些单独的数据任务是异步运行的,因此您需要某种方法来跟踪这些异步任务,并对它们的完成建立某种依赖关系

有几种可能的方法:

  • 典型的解决方案是使用调度组。在使用
    dispatch\u group\u Enter
    启动请求之前,请输入组,将使用
    dispatch\u group\u leave
    的组保留在完成处理程序中(异步调用),然后在循环结束时,提供一个
    dispatch\u group\u notify
    块,当所有“Enter”命令执行完毕时,该块将异步调用呼叫被相应的“离开”呼叫抵消:

  • 处理此问题的更复杂方法是将
    NSSessionDataTask
    包装在
    NSOperation
    子类中,然后可以使用数据任务操作和最终完成操作之间的依赖关系。您需要确保您的单个数据任务操作是“并发”操作(即,在异步数据任务完成之前,不要发出
    isFinished
    通知)。这种方法的好处是,您可以设置
    maxConcurrentOperationCount
    ,以限制在任何给定时间启动的请求数量。通常,您希望一次将其限制为3-4个请求

    注意,这还可以解决调度组方法可能遇到的超时问题。调度组不限制在任何给定时间提交的请求数量,而这可以通过
    NSOperation
    轻松实现

    有关更多信息,请参阅《并发编程指南》一节中关于“并发操作”的讨论

    有关在异步
    NSOperation
    子类中包装
    NSURLSessionTask
    请求的示例,请参见下半部分的简单实现。这个问题是针对一个不同的主题,但我在最后包含了一个
    NSOperation
    子类示例

  • 如果使用上载/下载任务而不是数据任务,则可以使用
    [NSURLSessionConfiguration backgroundSessionConfiguration]
    urlsessiondFinisheventsforbackgroundurlsession:
    nsurlsessionelegate
    将在所有任务完成且应用程序返回前台时被调用。(不过,有一点让人恼火的是,只有在下载完成时应用程序未处于活动状态时才会调用此方法:我希望有一个此委托方法的格式副本,即使下载完成时应用程序位于前台也会调用此方法。)

    当您询问数据任务(不能与后台会话一起使用)时,将后台会话与上载/下载任务一起使用具有后台操作的显著优势。如果您的过程真的需要10分钟(这看起来很特别),那么为后台会话重构这个过程可能会提供显著的优势

  • 我甚至不想提及这一点,但为了完整起见,我应该承认,理论上,您只需维护挂起数据任务的可变数组或字典,并且在每个数据任务完成后,从该列表中删除一项,如果它认为这是最后一项任务,然后手动启动完成过程


  • 您的任务已在completionHandler block.BTW中完成,如果使用此技术,请确保任务同步(例如使用信号量),否则您的组将在所有任务排队后“完成”,而不是在所有任务完成时。
     create group
     for (url in urls)
         enter group
         start_async_task
             when complete leave group
    
     wait on group to finish or supply a block to be run when completed
    
    - (void)findStationsByRoute {
        dispatch_group_t group = dispatch_group_create();
    
        for (NSString *stopID in self.allRoutes) {
            NSString     *urlString = [NSString stringWithFormat:@"http://truetime.csta.com/developer/api/v1/stopsbyroute?route=%@", stopID];
            NSURL        *url       = [NSURL URLWithString:urlString];
            NSURLRequest *request   = [NSURLRequest requestWithURL:url];
    
            dispatch_group_enter(group);   // enter group before making request
    
            NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                if(httpResponse.statusCode == 200){
                    NSError *jsonError;   // Note, do not initialize this with [[NSError alloc]init];
                    NSDictionary *stopLocationDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
                    NSArray *stopDirectionArray = [stopLocationDictionary objectForKey:@"direction"];
                    for (NSDictionary *stopDictionary in stopDirectionArray) {
                        NSArray *stop = [stopDictionary objectForKey:@"stop"];
                        [self.arrayOfStops addObject:stop];
                    }
                }
    
                dispatch_group_leave(group);  // leave group from within the completion handler
            }];
    
            [task resume];
        }
    
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // do something when they're all done
        });
    }