多線程異步獲取獲取服務(wù)端數(shù)據(jù)贮尖,全成功以后再返回主線程進(jìn)行操作的簡(jiǎn)單方法記錄
這次遇到項(xiàng)目是一個(gè)基金類的項(xiàng)目屿附,所以經(jīng)常會(huì)遇到一個(gè)頁(yè)面需要調(diào)用到好幾個(gè)接口的情況瓷炮,如何能又符合客戶的需求泪漂,又符合用戶的體驗(yàn)就是個(gè)比較有意思的事兒了咧七,這里基本就是用兩種辦法來(lái)針對(duì)不同情況
需要優(yōu)先展示UI 而后顯示數(shù)據(jù)的情況
這種情況下我用的方法是直接跳轉(zhuǎn)衰齐,然后在viewDidLoad
或viewWillAppear
異步調(diào)用所有的接口,在接口成功返回的時(shí)刷新對(duì)應(yīng)的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];
}
這樣就能輕松做到先展示頁(yè)面而后隨著數(shù)據(jù)加載而不斷刷新cell的需求了继阻,這也是一個(gè)提高tableview性能的好辦法【刷新的時(shí)候只刷新對(duì)應(yīng)的section或者row】
額外說(shuō)一下UITableViewRowAnimation這個(gè)動(dòng)畫(huà)的含義
typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
UITableViewRowAnimationFade, //淡入淡出
UITableViewRowAnimationRight, //從右滑入
UITableViewRowAnimationLeft, //從左滑入
UITableViewRowAnimationTop, //從上滑入
UITableViewRowAnimationBottom, //從下滑入
UITableViewRowAnimationNone, // 無(wú)動(dòng)畫(huà)
UITableViewRowAnimationMiddle, // available in iOS 3.2. attempts to keep cell centered in the space it will/did occupy
UITableViewRowAnimationAutomatic = 100 // 自動(dòng)動(dòng)畫(huà)耻涛,很難描述,但是動(dòng)作很大瘟檩,而且效果不錯(cuò)抹缕,可以自行試試
};
關(guān)于必須獲取所有數(shù)據(jù)后才進(jìn)行跳轉(zhuǎn)或者所有頁(yè)面的展示
這種情況也比較常見(jiàn),是需要先將好幾個(gè)接口的數(shù)據(jù)全加載好以后才能進(jìn)行主線程操作墨辛,在很多場(chǎng)景下都有需求卓研。主要使用的辦法是利用Dispatch Group來(lái)實(shí)現(xiàn)。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self loadData];
}
- (void)loadData {
// 這里最好加上加載狀態(tài)
[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(@"===全部執(zhí)行完畢");
[self.tableView reloadData];
// 在這兒把加載狀態(tài)結(jié)束
[SVProgressHUD dismissWithDelay:0.1];
});
}
#pragma mark - 數(shù)據(jù)請(qǐng)求
- (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);
}];
}
這樣就能做到在三個(gè)data都調(diào)用成功以后再進(jìn)行操作的效果了,同時(shí)奏赘,如果有錯(cuò)誤的返回或者其他需求只要改變r(jià)equestisScu()的返回就行了寥闪,可以隨機(jī)應(yīng)變