多线程异步获取获取服务端数据

多线程异步获取获取服务端数据,全成功以后再返回主线程进行操作的简单方法记录

这次遇到项目是一个基金类的项目,所以经常会遇到一个页面需要调用到好几个接口的情况,如何能又符合客户的需求,又符合用户的体验就是个比较有意思的事儿了,这里基本就是用两种办法来针对不同情况

需要优先展示UI 而后显示数据的情况

这种情况下我用的方法是直接跳转,然后在viewDidLoadviewWillAppear异步调用所有的接口,在接口成功返回的时刷新对应的cell或section

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self loadNetWork];
}

- (void)loadNetWork {
    // 接口1
    [LoadNetWork loadRequest1:@{} callback:^(NSDictionary *response) {
        self.data1 = response;
    }];

    // 接口2
    [LoadNetWork loadRequest2:@{} callback:^(NSDictionary *response) {
        self.data2 = response;
    }];

    // 接口3
    [LoadNetWork loadRequest3:@{} callback:^(NSDictionary *response) {
        self.data3 = response;
    }];
}

- (void)setData1:(NSDictionary *)data1 {
    _data1 = data1;
    [_tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}

- (void)setData2:(NSDictionary *)data2 {
    _data2 = data2;
    [_tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:1 inSection:1],[NSIndexPath indexPathForRow:1 inSection:2],[NSIndexPath indexPathForRow:1 inSection:3]] withRowAnimation:UITableViewRowAnimationNone];
}

- (void)setData3:(NSDictionary *)data3 {
    _data3 = data3;
    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationAutomatic];
}

这样就能轻松做到先展示页面而后随着数据加载而不断刷新cell的需求了,这也是一个提高tableview性能的好办法【刷新的时候只刷新对应的section或者row】

额外说一下UITableViewRowAnimation这个动画的含义

typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
    UITableViewRowAnimationFade,   //淡入淡出
    UITableViewRowAnimationRight,  //从右滑入      
    UITableViewRowAnimationLeft,   //从左滑入
    UITableViewRowAnimationTop,     //从上滑入
    UITableViewRowAnimationBottom,  //从下滑入
    UITableViewRowAnimationNone,            // 无动画
    UITableViewRowAnimationMiddle,          // available in iOS 3.2.  attempts to keep cell centered in the space it will/did occupy
    UITableViewRowAnimationAutomatic = 100  // 自动动画,很难描述,但是动作很大,而且效果不错,可以自行试试
};

关于必须获取所有数据后才进行跳转或者所有页面的展示

这种情况也比较常见,是需要先将好几个接口的数据全加载好以后才能进行主线程操作,在很多场景下都有需求。主要使用的办法是利用Dispatch Group来实现。

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self loadData];
}

- (void)loadData {
    // 这里最好加上加载状态
    [SVProgressHUD show];
    
    dispatch_group_t group = dispatch_group_create();
    
    //接口1
    dispatch_group_enter(group);
    [self loadData1IsScu:^(BOOL isScu) {
        dispatch_group_leave(group);
    }];
    
    //接口2
    dispatch_group_enter(group);
    [self loadData2IsScu:^(BOOL isScu) {
        dispatch_group_leave(group);
    }];
    
    //接口3
    dispatch_group_enter(group);
    [self loadData3IsScu:^(BOOL isScu) {
        dispatch_group_leave(group);
    }];
    
    dispatch_group_notify(group,dispatch_get_main_queue(), ^(){
        NSLog(@"===全部执行完毕");
        [self.tableView reloadData];
        // 在这儿把加载状态结束
        [SVProgressHUD dismissWithDelay:0.1];
    });
}

#pragma mark - 数据请求
- (void)loadData1IsScu:(void(^)(BOOL isScu))requestisScu {
    [LoadNetWork loadRequest1:@{} callback:^(NSDictionary *response) {
        self.data1 = response;
        requestisScu(YES);
    }];
}

- (void)loadData2IsScu:(void(^)(BOOL isScu))requestisScu {
    [LoadNetWork loadRequest1:@{} callback:^(NSDictionary *response) {
        self.data2 = response;
        requestisScu(YES);
    }];
}

- (void)loadData3IsScu:(void(^)(BOOL isScu))requestisScu {
    [LoadNetWork loadRequest3:@{} callback:^(NSDictionary *response) {
        self.data3 = response;
        requestisScu(YES);
    }];
}

这样就能做到在三个data都调用成功以后再进行操作的效果了,同时,如果有错误的返回或者其他需求只要改变requestisScu()的返回就行了,可以随机应变

你可能感兴趣的:(多线程异步获取获取服务端数据)