为什么在检索json数据和显示viewcontroller之间存在长时间延迟

时间:2014-08-07 03:40:52

标签: ios objective-c

我遇到了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";
}

1 个答案:

答案 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";
    }