需求:利用HealthKit從iOS系統(tǒng)獲取最近一周運(yùn)動(dòng)步數(shù)
由于使用的HealthKit接口是在子線程執(zhí)行的, 若使用for循環(huán)遍歷查詢多天數(shù)據(jù)存入數(shù)組的話會(huì)由于多線程不同步的原因?qū)е屡判蚧靵y
一種思路就是給查詢出的每一天的數(shù)據(jù)分配一個(gè)日期的id, 查詢結(jié)束后再根據(jù)日期給數(shù)組排序(怎么判斷所有線程執(zhí)行完?用KVO監(jiān)聽(tīng)數(shù)組個(gè)數(shù)?覺(jué)得這種有點(diǎn)麻煩還沒(méi)有實(shí)現(xiàn),只是同事給的一個(gè)建議)
由于系統(tǒng)提供的方法有block回調(diào), 于是想到用block回調(diào), 封裝一個(gè)遞歸方法, 利用遞歸實(shí)現(xiàn)線程同步和循環(huán)查詢
最終截圖:
封裝的遞歸方法:
//利用當(dāng)前date和當(dāng)前weekday獲取當(dāng)前周的運(yùn)動(dòng)步數(shù)
-(void)recursionGetSteps:(NSDate *)date muArray:(NSMutableArray *)muArray weekday:(NSInteger)weekday{
[[HealthKitManage shareInstance] getStepOfDate:date Count:^(double value, NSError *error) {
NSString *step =[NSString stringWithFormat:@"%zd",(NSInteger)value];
NSLog(@"這里這里這里這里%zd--%@",weekday,[NSThread currentThread]);
[muArray addObject:step];
NSLog(@"%@",muArray[0]);
self.weekSteps = muArray;
//若數(shù)據(jù)讀取結(jié)束跳出遞歸,回主線程刷新UI
if (self.weekSteps.count == weekday) {
dispatch_sync(dispatch_get_main_queue(), ^{
self.weekSteps = (NSMutableArray *)[[muArray reverseObjectEnumerator] allObjects];
[self configUI];
});
}else{
NSDate *preDate = [HealthKitManage preDateOfDate:date];
[self recursionGetSteps:preDate muArray:muArray weekday:weekday];
}
}];
}
注: HealthKitManage是對(duì)HealthKit請(qǐng)求授權(quán)和數(shù)據(jù)查詢封裝好的一個(gè)工具類
或許有更好的實(shí)現(xiàn)多線程同步讀取數(shù)據(jù)的方法, 歡迎留言相互交流.demo有空會(huì)放github