简体   繁体   中英

Objective-c TableView Refresh With dispatch_sync error

Hello I have working simple tableview json parsing codes. But i want to do reload tableview in background everytime i added dispatch_sync codes but don't working my codes under.

NSArray * jsonArray;
NSMutableArray * array1;


- (void)viewDidLoad {
    [super viewDidLoad];


   NSURL * url = [NSURL URLWithString:@"http://bla.com/test2.json"];

    NSURLRequest * urlReq = [NSURLRequest requestWithURL:url];

    NSError * error;

    NSData * data = [NSURLConnection sendSynchronousRequest:urlReq returningResponse:nil error:&error];

    NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

    NSLog(@"%@",jsonDict);

    jsonArray = [jsonDict objectForKey:@"worldpopulation"];

    NSLog(@"%@",jsonArray);

    array1 =[[NSMutableArray alloc]init];

}

- (void)main
{

    dispatch_sync(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
}



-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return jsonArray.count;

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellid=@"CustomCell";
    CustomTableViewCell *cell=(CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellid];;


    if(cell==nil)
    {
        cell=[[CustomTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid];

    }



    for ( NSDictionary * dict in jsonArray) {

        NSString * country = [dict objectForKey:@"country"];

        [array1 addObject:country];

    }

    cell.nameLabel.text= [array1 objectAtIndex:indexPath.row];



    return cell;
}

Main.m

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

I added only needed codes . I need to fix it . Thanks for your help !

First, performing synchronous network operations on the main thread is a bad idea - it will make your app UI 'freeze' until the operation completes, which in the case of a slow (or no) network could be a long time.

Secondly, you should move the loading code into its own function that you call from viewDidLoad - this way you can easily call it again if you want to reload the data.

Thirdly, your cellForRowAtIndexPath is iterating your entire jsonArray for each cell to no purpose.

Finally, NSURLConnection is deprecated in iOS 9 so you should migrate to NSURLSession if you are targeting iOS7 and later (if you want to run on iOS prior to iOS 7 then you will need to keep using NSURLConnection)

I would suggest the following:

@interface MyViewController () <UITableViewDelegate,UITableViewDataSource>

@property (strong,nonatomic) NSArray *jsonArray;

@end

@implementation MyViewController


- (void)viewDidLoad {
    [super viewDidLoad];

    self.jsonArray=[NSArray new];
    [self loadJSON];
}

-(void)loadJSON {

    NSURL * url = [NSURL URLWithString:@"http://bla.com/test2.json"];
    NSURLSession *session=[NSURLSession sharedSession];

   [session dataTaskWithRequest:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error!=nil) {
            NSLog(@"Something went wrong:%@",error);
        } else {
            NSError *jsonError;
            NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonEerror];
            if (jsonError != nil) {
                NSLog(@"JSON isn't right:%@",jsonError);
            } else {
                self.jsonArray = jsonDict[@"worldpopulation"];
                dispatch_async(dispatch_get_main_queue(),^{
                    [self.tableview reloadData];
                }); 
            }
    }];

}


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.jsonArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellid=@"CustomCell";
    CustomTableViewCell *cell=(CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellid forIndexPath:indexPath];;

    NSDictionary *entryDict=self.jsonArray[indexPath.row];
    NSString *countryName=entryDict[@"country"];

    cell.nameLabel.text= countryName;
    return cell;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM