複数の非同期処理を待つのにWindowsAPIのWaitForMultipleObjects的なメソッドがないかなと探してたんですが、調べるの結構大変だったので、自分用にメモを残しておきます。
dispatch_group_t group = dispatch_group_create();
[self.arrayLocalSearch removeAllObjects];
NSError* error = nil;
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Location"
inManagedObjectContext:[MapData sharedManager].managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:40];
NSArray* locations = [[MapData sharedManager].managedObjectContext executeFetchRequest:fetchRequest error:&error];
if(error){
LOG(@"Unresolved error %@ %@",error,[error userInfo]);
}
for(Location* location in locations){
dispatch_group_enter(group);
if (!location.geocoding) {
[self searchShopLocation:location
block:^{
dispatch_group_leave(group);
}];
}else{
CustomMapItem* customItem = [[CustomMapItem alloc] init];
customItem.location = location;
self.mapAnnotations[location.name] = customItem;
dispatch_group_leave(group);
}
}
//全ての非同期処理が完了したら、メインスレッドで実行される
dispatch_group_notify(group,
dispatch_get_main_queue(),
^{
//NSLog(@"done");
[self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist
NSMutableArray* array = [NSMutableArray arrayWithCapacity:self.mapAnnotations.count];
for (id key in [self.mapAnnotations keyEnumerator]) {
[array addObject:self.mapAnnotations[key]];
}
[self.mapView addAnnotations:array];
});
作成中のアプリのコードをサンプルに流用したのでわかりにくいですが、ポイントとしては、
- dispatch_group_t group = dispatch_group_create();
- dispatch_group_notify(group,...
- dispatch_group_enter(group);
- dispatch_group_leave(group);
1がグループを作成します。
2がグループの処理が終わるまで待機する関数です。WaitForMultipleObjects関数に相当します。
3と4がCreateEvent(ResetEvent),SetEventに相当します。
上記のイメージで扱うとわかりやすいと思います。