我正在尝试在循环中运行一个块并在NSMutableArray中收集结果。我遇到的问题是,由于它是异步的,我很难找到所有块何时完成执行。我正在尝试将[数组计数]与块调用的数量进行比较。我的想法是,这只会触发一次,但我发现'我做了!'将永远不会被记录或将被多次记录。我也觉得这是一个hacky解决方案,但我想不出更好的方法。
很抱歉长代码块但是我输入了所有需要的代码,所以如果有人想要,他们可以复制&粘贴并查看我得到的结果。我的问题的实际肉和土豆开始于大约2/3的while循环。
很明显,我是iOS开发的新手,所以欢迎任何其他建设性的批评。
NSDate *now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *zeroOutAfterHourComponents = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:[NSDate date]];
NSDate *gregorianNow = [gregorian dateFromComponents:zeroOutAfterHourComponents];
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
[componentsToSubtract setDay:-7];
//[componentsToSubtract setHour:-24];
NSDate *startingDate = [gregorian dateByAddingComponents:componentsToSubtract toDate:gregorianNow options:0];
NSDateComponents *addAnHourComponent = [[NSDateComponents alloc] init];
[addAnHourComponent setHour:1];
NSDate *startingDatePlusAnHour = [gregorian dateByAddingComponents:addAnHourComponent toDate:startingDate options:0];
CMStepCounter *stepCounter = [CMStepCounter new];
NSOperationQueue *stepQueue = [NSOperationQueue new];
stepQueue.name = @"Step Counter Queue";
__block NSMutableArray *dateKeyAndSccSteps = [NSMutableArray new];
NSTimeInterval time = [now timeIntervalSinceDate:startingDate];
int hours = time / 60 / 60;
// + 1 is added to take account of the current hour
int totalDictionaryCount = hours + 1;
NSLog(@"totalDictionaryCount: %d", hours);
NSLog(@"StartingDate: %@", startingDate);
NSLog(@"StartingDatePlusAnHour: %@", startingDatePlusAnHour);
NSLog(@"Now: %@", now);
while ([startingDate compare:now] == NSOrderedAscending) {
[stepCounter queryStepCountStartingFrom:startingDate to:startingDatePlusAnHour toQueue:stepQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
NSDateFormatter *formatterForDate = [[NSDateFormatter alloc] init];
[formatterForDate setDateFormat:@"yyyy-MM-dd"];
NSString *dateKey =[NSString stringWithFormat:@"%@", [formatterForDate stringFromDate: startingDate]];
[dateKeyAndSccSteps addObject:@[dateKey, @"TestValue"]];
NSLog(@"array count: %lu - totalDictionaryCount: %d", (unsigned long)[dateKeyAndSccSteps count], totalDictionaryCount);
if ([dateKeyAndSccSteps count] == totalDictionaryCount){
NSLog(@"I MADE IT!");
}
}];
startingDate = startingDatePlusAnHour;
startingDatePlusAnHour = [gregorian dateByAddingComponents:addAnHourComponent toDate:startingDatePlusAnHour options:0];
};
NSLog(@"Finished While Loop: %@", now);
更新 - 2013-12-13
我使用调度组更新了我的while循环。我还改变了stepCounter块以使用[NSOperationQueue mainQueue]。
它有效,但我不确定我是否正确使用它们。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
while ([startingDate compare:now] == NSOrderedAscending) {
dispatch_group_async(group, queue, ^{
[stepCounter queryStepCountStartingFrom:startingDate to:startingDatePlusAnHour toQueue:[NSOperationQueue mainQueue] withHandler:^(NSInteger numberOfSteps, NSError *error) {
<< same existing code as original >>
}];
});
startingDate = startingDatePlusAnHour;
startingDatePlusAnHour = [gregorian dateByAddingComponents:addAnHourComponent toDate:startingDatePlusAnHour options:0];
};