Ios 从JSON下载数据并存储到CoreData,在后台下载数据时同时显示

Ios 从JSON下载数据并存储到CoreData,在后台下载数据时同时显示,ios,objective-c,iphone,json,core-data,Ios,Objective C,Iphone,Json,Core Data,我正在解析JSON中的数据并将其存储到CoreData中,同时我正在将数据显示到tableview中,但我遇到的问题是数据仅在下载完成后才显示,但我不想这样,我想在后台下载数据,并在处理下载时显示数据。我如何做到这一点 -(void)connectionDidFinishLoading:(NSURLConnection *)connection { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO

我正在解析JSON中的数据并将其存储到CoreData中,同时我正在将数据显示到tableview中,但我遇到的问题是数据仅在下载完成后才显示,但我不想这样,我想在后台下载数据,并在处理下载时显示数据。我如何做到这一点

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    arrayData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSError *error;
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    context = [appDelegate managedObjectContext];

    for (int i = 0; i < [arrayData count]; i++) {

        idNum = [arrayData objectAtIndex:i][@"id"];
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Discount"];
        [request setPredicate:[NSPredicate predicateWithFormat:@"cID = %@",idNum]];
        [request setFetchLimit:1];
        NSUInteger count = [context countForFetchRequest:request error:&error];
        if (count == NSNotFound) {
            NSLog(@"ERROR");
        }else if (count == 0) {
            NSLog(@"New Data Coming");

            name  = [arrayData objectAtIndex:i][@"name"];
            summary = [arrayData objectAtIndex:i][@"summary"];
            region = [arrayData objectAtIndex:i][@"region"];
            imageURL = [arrayData objectAtIndex:i][@"images"][@"logo"];

            id  benefits1 = [arrayData objectAtIndex:i][@"benefits"];
            benefiteString = [NSString stringWithFormat:@"%@ %@",[benefits1 objectAtIndex:0][@"key"],[benefits1 objectAtIndex:0][@"value"]];
            NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
            dateUpdate = [arrayData objectAtIndex:i][@"updated_at"];
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
            [dateFormatter setDateFormat: @"yyyy-MM-dd'T'HH:mm:ss.sssZ"];
            NSDate *date =[dateFormatter dateFromString:dateUpdate];
            [dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
            NSLog(@"DAte : %@",date);
            Discount * d = [NSEntityDescription insertNewObjectForEntityForName:@"Discount" inManagedObjectContext:context];
            d.name = name;
            d.summary = summary;
            d.regions = region;
            d.cID = idNum;
            d.imageLogo = data;
            d.updated_at = date;
            d.benefits = benefiteString;
            if (![context save:&error]) {
                NSLog(@"Getting error while saving data");
            }
            else{
                NSLog(@"Saved");
            }
        }

    }
    [sharedAppDelegate dismissGlobalHUD];
    [listTableView reloadData];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_myArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    customCellClass = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (customCellClass == nil)
    {
        customCellClass = [[CellCustom alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }
    customCellClass.nameLabel.text = [[_myArray objectAtIndex:indexPath.row]name];
    customCellClass.cityLabel.text =[[_myArray objectAtIndex:indexPath.row]regions];
    customCellClass.detailLabel.text = [[_myArray objectAtIndex:indexPath.row]summary];

    NSData * d = [[_myArray objectAtIndex:indexPath.row]imageLogo];
    customCellClass.mainImage.image = [UIImage imageWithData:d];

    customCellClass.benefitsLabel.text = [[_myArray objectAtIndex:indexPath.row]benefits];
    [sharedAppDelegate dismissGlobalHUD];
    return customCellClass;
}

-(void)dataDidSave
{

    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Discount" inManagedObjectContext:context]; [fetchRequest setEntity:entity];
    [fetchRequest setEntity:entity];
    NSError *error = nil;
    NSArray *result = [context executeFetchRequest:fetchRequest error:&error];

    self.myArray = result;
    [listTableView reloadData];
}
-(void)viewWillAppear:(BOOL)animated
{
    [sharedAppDelegate showGlobalProgressHUDWithTitle:@"Loading..."];
    [self dataDidSave];
}

在ConnectionIDFinishLoading中:尝试以下操作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {
   // Process your data and then incrementally call 
      dispatch_async(dispatch_get_main_queue(),^ {
           [listTableView reloadData];
      });
    }
});

是的,下载完成后,它将添加到阵列并显示,但是否有一种方式,即下载必须在后台进行,并以异步方式显示下载您的ConnectionIDFinishLoading:可能由主线程执行。您可以通过记录[NSThread isMainThread]来检查这一点。如果是这样,我会将ConnectiondFinishLoading:的整个处理程序扔到后台队列中,并将UI更新从该队列中排队。我不知道您是否有此解决方案的任何示例请参阅我粘贴的示例代码。UI更新只能在主线程1上进行。在XCode中,可以在ConnectionIDFinishLoading上放置一个断点,这样就可以看到哪个线程正在运行。很可能您实际上正在线程1上运行,这意味着在该线程上的所有处理完成之前,UITableView刷新不会发生。解决方案是将繁重的数据处理移动到后台线程,并根据需要递增地调度主线程线程1以刷新表。只需复制并将其放入didfinishloading?