我正在使用 AFNetworking并使用操作队列(类似于 NSOperationQueue)将一堆请求排队到 Clear Read API .
我基本上有一个 URL 数组,我根据每个请求创建单独的请求,将每个请求排入队列,然后批量执行请求。它们返回,一次一个,然后我添加时间戳,然后将它们添加到核心数据,这是我的 TableView 的源,因此 TableView 被填充。
仅当项目成功返回时才会发出时间戳。这意味着项目将根据返回时间而不是原始 URLs 数组的顺序进行排序。因此,返回时间较短的请求(API 处理的文本较少)的时间戳较早,因此被认为比由于文本量较大而时间戳较晚的项目更早。就正确排序而言,情况显然不是这样。
最后,即使我有一组按正确顺序调用 API 的 URL,我的 TableView 也会根据 API 返回项目的时间进行排序。
这是我的代码:
- (void)addArticlesFromURLs:(NSArray *)URLs fromSource:(NSString *)source {
// Restrict amount of operations that can occur at once
[[AFClearReadClient sharedClient].operationQueue setMaxConcurrentOperationCount:3];
// Create an array to hold all of our requests to make
NSMutableArray *requestOperations = [[NSMutableArray alloc] init];
for (NSString *URL in URLs) {
// Create the request from the article's URL
NSMutableURLRequest *request = [[AFClearReadClient sharedClient] requestWithMethod:@"GET" path:[NSString stringWithFormat:@"/v1/clear?url=%@&format=json", URL] parameters:nil];
// Create the request operation and specify behaviour on success and failure
AFHTTPRequestOperation *requestOperation = [[AFClearReadClient sharedClient] HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Get the item NSDictionary from the JSON responseObject
NSDictionary *item = [responseObject objectForKey:@"item"];
// Get the values needed to create an article
NSString *title = [item objectForKey:@"title"];
NSString *URL = [item objectForKey:@"link"];
NSString *body = [item objectForKey:@"description"];
// Replace HTML entities with their actual characters
title = [title stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
// Remove all HTML and formatting from body so only plain-text remains
body = [self removeHTMLAndFormatting:body];
// Add it to CoreData if there's actual content (easiest way to tell is checking body)
if (![body isEqualToString:@""]) {
NSManagedObjectContext *context = self.managedObjectContext;
ArticleInfo *articleInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ArticleInfo" inManagedObjectContext:context];
articleInfo.source = source;
articleInfo.body = body;
articleInfo.title = title;
articleInfo.url = URL;
articleInfo.timeStamp = [NSDate date];
NSError *error;
[context save:&error];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Request operation error: %@", error);
}];
// Save the request operation in an NSArray so all can be enqueued later
[requestOperations addObject:requestOperation];
}
// Enqueue the request operations
[[AFClearReadClient sharedClient] enqueueBatchOfHTTPRequestOperations:requestOperations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
[self.tableView reloadData];
} completionBlock:^(NSArray *operations) {
[self.tableView reloadData];
}];
}
我将如何改变它,以便我的 tableview 中的项目按正确的顺序排列(最新的在最前面)?
最佳答案
使用 userInfo
。
AFHTTPRequestOperation
是AFURLConnectionOperation
的子类,AFURLConnectionOperation
声明了一个userInfo
字典,不被触及就通过。它的目的是让您添加操作完成时需要使用的任何数据。在将操作添加到队列之前,请执行以下操作:
[requestOperation setUserInfo:@{ @"timestamp" : [NSDate date] };
在你的完成 block 中获取它作为
NSDate *timestamp = [operation userInfo][@"timestamp"];
时间戳将反射(reflect)操作添加到队列的顺序。
关于ios - 对许多请求进行排队,然后根据添加的时间进行排序,但项目最终会根据从请求中收到的时间进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17459599/