确保异步方法的执行顺序与调用顺序相同

时间:2016-04-25 21:36:47

标签: ios concurrency nsurlconnection

假设我有3个异步方法,它们都做同样的事情:将一些数据发送到服务器并将响应数据添加到数组(所有这些都添加到同一个数组中)。

我同时调用这些方法,但它们向服务器发送不同数量的数据。

如果第一种方法向服务器发送的数据多于第三种方法,则第三种方法将更快地恢复响应,从而更快地将数据添加到数组中。响应数据由坐标组成,因此它们在数组中的顺序很重要。

我怎样才能确定,即使第三种方法比第一种方法或第二种方法更快地获得repsonse,它也不会在之前的方法之前将数据添加到数组中?因此,保留数组中坐标的顺序。

方法是NSURLConnection,它们都发送异步请求。

编辑:这是工作代码:

 //Array of snapped points from the JSON
            NSArray *snappedPoints = [result objectForKey:@"snappedPoints"];

            NSMutableArray *locationsArray = [[NSMutableArray alloc] init];

            //Loop through the snapped points array and add each coordinate to a temporary array
            for (int i = 0; i<[snappedPoints count]; i++) {
                NSDictionary *location = [[snappedPoints objectAtIndex:i] objectForKey:@"location"];

                double latitude = [[location objectForKey:@"latitude"] doubleValue];
                double longitude = [[location objectForKey:@"longitude"] doubleValue];

                CLLocation *loc = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];

                [locationsArray addObject:loc];

            }


            //Add these temporary location arrays to the dictionary with the key as the request number
            [tempLocationDictionary setObject:locationsArray forKey:[NSString stringWithFormat:@"%i",requestNumber]];

            //If all requests have completed get the location arrays from the dicitonary in the same order as the request were made
            if([tempLocationDictionary count] == numberOfRequests){

                //Just a path because I am drawing these coordinates on a map later
                GMSMutablePath *path = [GMSMutablePath path];

                //Loop through the dictionary and get the location arrays in the right order
                for (int i = 0; i<[tempLocationDictionary count]; i++) {
                    //Create a dummy array
                    NSArray *array = [tempLocationDictionary objectForKey:[NSString stringWithFormat:@"%i",i+1]];

                    //Get the coordinates from the array which we just got from the dictionary
                    for (CLLocation *location in array) {
                        [path addCoordinate:location.coordinate];

                    }
                }

2 个答案:

答案 0 :(得分:2)

一种方法是将NSURLConnection替换为NSURLSession及其相关类。它更新,通常是一个更好的选择。对于您的具体情况,您可以使用自定义NSURLSessionConfigurationHTTPMaximumConnectionsPerHost设置为1.这样就可以强制连接按顺序运行,解决您的问题。

当然,没有同时连接可能会减慢速度。在这种情况下,您必须暂时累积数据,而不将其添加到您的阵列,并且仅在所有连接完成时更新阵列。有多种方法可以执行此操作,具体取决于从服务器返回的确切数据。

一种相对简单的方法:如果您知道您将始终拥有三个连接,请使用带有整数NSMutableDictionary个对象的NSNumber作为键。在每次连接后,您都会执行类似

的操作
mutableDictionary[@1] = // your server data here

使用@2@3进行其他连接。每次添加数据时,请检查是否有所有三个数据,如果是,则将所有内容添加到数组中。还有很多其他的方法,关键是要有某种临时结构,你可以(a)累积数据直到所有连接完成,(b)跟踪哪个数据来自哪个连接,或者简单按数字,或通过URL,或由服务器提供的其他一些唯一数据。

答案 1 :(得分:0)

这是NSOperationQueue和依赖项要解决的问题。

从WWDC 2015查看Advanced NSOperations [transcript]:

  

当WWDC应用程序启动时,我们需要进行一系列设置。

     

首先,我们要下载一个小配置文件,这个文件会告诉我们一些小问题,例如最近支持的应用程序版本,我们启用了哪些功能等等。

     

因此,在我们下载此文件后,我们将执行版本检查以确保您运行的是最新版本的WWDC应用程序。

     

然后在我们检查应用程序的版本后,我们可以开始下载有用的信息,例如我们在“新闻”选项卡中显示的新闻和会议日程。

     

在我们下载了时间表之后,我们就可以开始导入您已保存到iCloud的所有收藏,您已提交的任何反馈,以便您可以在应用中看到它,我们也将开始下载视频列表。

在描述这些操作时应用依赖关系应该很好地排序。