确保异步方法的执行顺序与它们被调用的顺序相同
Make sure async methods execute in same order as they were called
假设我有 3 个异步方法,它们都做同样的事情:将一些数据发送到服务器并将响应数据添加到数组(所有这些都添加到同一个数组)。
我同时调用了这些方法,但它们向服务器发送的数据量不同。
如果第一种方法向服务器发送的数据比第三种方法多,第三种方法会更快得到响应,从而更快地将数据添加到数组中。响应数据由坐标组成,因此它们在数组中的顺序很重要。
我如何确保,即使第三种方法比第一种或第二种方法更快获得响应,它也不会在前面的方法之前将数据添加到数组中?因此,保留数组中坐标的顺序。
这些方法是 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];
}
}
一种方法是将 NSURLConnection
替换为 NSURLSession
及其相关的 类。它较新,通常是更好的选择。对于您的具体情况,可以使用自定义 NSURLSessionConfiguration
,您可以将 HTTPMaximumConnectionsPerHost
设置为 1。这样连接将被强制按顺序 运行,从而解决您的问题。
当然,没有同时连接可能会减慢速度。在这种情况下,您必须暂时 累积数据而不 将其添加到您的数组中,并且仅在所有连接完成后才更新数组。根据从服务器返回的具体数据,您可以通过多种方式执行此操作。
一种相对简单的方法:如果您知道您将始终拥有三个连接,请使用带有整数 NSNumber
对象的 NSMutableDictionary
作为键。每次连接后你会做类似
的事情
mutableDictionary[@1] = // your server data here
对其他连接使用@2
或@3
。每次添加数据时,请检查是否有所有这三个数据的结果,如果有,请将所有数据添加到数组中。有很多其他方法可以解决这个问题,关键是要有某种临时结构,您可以在其中 (a) 累积数据直到所有连接都完成,以及 (b) 跟踪哪些数据来自哪个连接,或者简单地按数字,或按 URL,或按服务器提供的其他一些唯一数据。
这个问题要用NSOperationQueue和依赖来解决
从 WWDC 2015 查看 Advanced NSOperations [transcript]:
When the WWDC app starts up, there's a bunch of setup that we need to do.
First, we are going to download a small configuration file, and this file will tell us small things like what's the most recently supported version of the application, what features we have enabled, and so on.
So after we download this file, we are going to perform a version check to make sure that you are running the latest version of the WWDC app.
And then after we check the version of the app, we can start downloading useful pieces of information, such as the news that we show in the News tab and the schedule for the conference.
After we've downloaded the schedule, then we can start importing any favorites that you've saved to iCloud, any feedback that you've submitted so you can see it in the app, and we are also going to start downloading the list of videos.
按照它们对这些操作的描述应用依赖项应该可以很好地对您进行分类。
假设我有 3 个异步方法,它们都做同样的事情:将一些数据发送到服务器并将响应数据添加到数组(所有这些都添加到同一个数组)。
我同时调用了这些方法,但它们向服务器发送的数据量不同。
如果第一种方法向服务器发送的数据比第三种方法多,第三种方法会更快得到响应,从而更快地将数据添加到数组中。响应数据由坐标组成,因此它们在数组中的顺序很重要。
我如何确保,即使第三种方法比第一种或第二种方法更快获得响应,它也不会在前面的方法之前将数据添加到数组中?因此,保留数组中坐标的顺序。
这些方法是 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];
}
}
一种方法是将 NSURLConnection
替换为 NSURLSession
及其相关的 类。它较新,通常是更好的选择。对于您的具体情况,可以使用自定义 NSURLSessionConfiguration
,您可以将 HTTPMaximumConnectionsPerHost
设置为 1。这样连接将被强制按顺序 运行,从而解决您的问题。
当然,没有同时连接可能会减慢速度。在这种情况下,您必须暂时 累积数据而不 将其添加到您的数组中,并且仅在所有连接完成后才更新数组。根据从服务器返回的具体数据,您可以通过多种方式执行此操作。
一种相对简单的方法:如果您知道您将始终拥有三个连接,请使用带有整数 NSNumber
对象的 NSMutableDictionary
作为键。每次连接后你会做类似
mutableDictionary[@1] = // your server data here
对其他连接使用@2
或@3
。每次添加数据时,请检查是否有所有这三个数据的结果,如果有,请将所有数据添加到数组中。有很多其他方法可以解决这个问题,关键是要有某种临时结构,您可以在其中 (a) 累积数据直到所有连接都完成,以及 (b) 跟踪哪些数据来自哪个连接,或者简单地按数字,或按 URL,或按服务器提供的其他一些唯一数据。
这个问题要用NSOperationQueue和依赖来解决
从 WWDC 2015 查看 Advanced NSOperations [transcript]:
When the WWDC app starts up, there's a bunch of setup that we need to do.
First, we are going to download a small configuration file, and this file will tell us small things like what's the most recently supported version of the application, what features we have enabled, and so on.
So after we download this file, we are going to perform a version check to make sure that you are running the latest version of the WWDC app.
And then after we check the version of the app, we can start downloading useful pieces of information, such as the news that we show in the News tab and the schedule for the conference.
After we've downloaded the schedule, then we can start importing any favorites that you've saved to iCloud, any feedback that you've submitted so you can see it in the app, and we are also going to start downloading the list of videos.
按照它们对这些操作的描述应用依赖项应该可以很好地对您进行分类。