我遇到了JSON数据检索和UITableViewController启动之间长时间延迟的问题。
下面的方法使用从UITableViewControllers初始化程序调用的硬编码查询,并在2秒内检索并显示数据。
- (void)productsQuery
{
NSString *requestString = @"http://192.168.2.10/testQueries.php?Product_Description=tea";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSArray *returnedItems =
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
for (int i = 0; i < [returnedItems count]; i++) {
NSDictionary *item = [returnedItems objectAtIndex:i];
NSNumber *nBay = [item objectForKey:@"Bay_Number"];
NSNumber *nShelf = [item objectForKey:@"Shelf_Number"];
NSNumber *coordX = [item objectForKey:@"CoordinateX"];
NSNumber *coordY = [item objectForKey:@"CoordinateY"];
TNWProduct *product =[[TNWProduct alloc]
initWithProductDescription:[item objectForKey:@"Product_Description"]
aisleNumber:[item objectForKey:@"Aisle_Number"]
bay:[nBay intValue]
shelf:[nShelf intValue]
nonAisleLocation:[item objectForKey:@"Location_Description"]
coordinateX:[coordX intValue]
coordinateY:[coordY intValue]];
[self.productList addObject:product];
}
NSLog(@"%@", self.productList);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}];
[dataTask resume];
}
然后调整该方法并将其移动到UIView控制器,以便用户可以输入查询。
JSON数据仍然会在2秒内被检索并添加到NSMutableArray _productList,因为它在NSLog调用的控制台中显示,但在启动ProductListViewController之前,它似乎什么也不做5-15秒。
@interface TNWSearchViewController () <UITextFieldDelegate>
@property (weak, nonatomic) NSString *userQuery;
@property (weak, nonatomic) IBOutlet UIToolbar *toolbar;
@property (weak, nonatomic) IBOutlet UITextView *informationMessages;
@property (nonatomic) NSURLSession *session;
@property (nonatomic, strong) NSMutableArray *productList;
@property (nonatomic, strong) NSArray *returnedItems;
@end
@implementation TNWSearchViewController
.
.
.
.
- (void)productQuery:(NSString *)query
{
if ([_productList count] > 0 ) {
[_productList removeAllObjects];
}
NSMutableString *requestString = [@"http://192.168.2.10/testQueries.php?Product_Description=" mutableCopy];
[requestString appendString:query];
NSString *escapedRequestString = [requestString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", escapedRequestString);
NSURL *url = [NSURL URLWithString:escapedRequestString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
_returnedItems =
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
//NSLog(@"Returned items = %@", _returnedItems);
for (int i = 0; i < [_returnedItems count]; i++) {
NSDictionary *item = [_returnedItems objectAtIndex:i];
//NSLog(@"Item = %@", item);
NSNumber *nBay = [item objectForKey:@"Bay_Number"];
NSNumber *nShelf = [item objectForKey:@"Shelf_Number"];
NSNumber *coordX = [item objectForKey:@"CoordinateX"];
NSNumber *coordY = [item objectForKey:@"CoordinateY"];
TNWProduct *product =[[TNWProduct alloc]
initWithProductDescription:[item objectForKey:@"Product_Description"]
aisleNumber:[item objectForKey:@"Aisle_Number"]
bay:[nBay intValue]
shelf:[nShelf intValue]
nonAisleLocation:[item objectForKey:@"Location_Description"]
coordinateX:[coordX intValue]
coordinateY:[coordY intValue]];
NSLog(@"%@", product);
[_productList addObject:product];
}
NSLog(@"Product list = %@", self.productList);
if ( [_productList count] > 0 ) {
TNWProductListViewController *plvc =
[[TNWProductListViewController alloc] initWithStyle:UITableViewStylePlain];
plvc.productList = [self.productList mutableCopy];
[self.navigationController pushViewController:plvc animated:YES];
} else {
_informationMessages.text = @"No matches found";
}
}];
[dataTask resume];
}
移动for循环中的代码块和[dataTask resume]
下面的if / else语句会导致应用程序按预期加载UITableView,但不再可以访问_returnedItems中的数据。
协助表示赞赏。
for (int i = 0; i < [_returnedItems count]; i++) {
.
.
.
} else {
_informationMessages.text = @"No matches found";
}
答案 0 :(得分:0)
将ViewController的创建和调用移动到dispatch_async块,如下所示修复了问题。
谢谢Fonix。
dispatch_async(dispatch_get_main_queue(), ^{
if ( [[[TNWProductList productsStore] allProducts] count] > 0 ) {
TNWProductListViewController *plvc =
[[TNWProductListViewController alloc] initWithStyle:UITableViewStylePlain];
[self.navigationController pushViewController:plvc animated:YES];
} else {
_informationMessages.text = @"No matches found";
}