次の動作を引き起こす特別なプロパティ NSRunLoop を見つけようとしています。
まず、私がやろうとしているのは、先に進む前に CLGeocoder の実行が完了するのを待つことです。完了ブロックを使用すると、コードは次のようになります。
if (/* loc has valid coordinates */)
[gc reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError error){
//do things
[gc reverseGeocodeLocation:newloc completionHandler:^(NSArray *placemarks, NSError error){
//do more things with newloc
// MOVE TO NEXT VIEW
}
}
else if (/*still have to check for newloc*/)
[gc reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError error){
//do things
//MOVE TO NEXT VIEW
残念ながら、//do things
これらのブロックの部分は冗長であり、CLGeocoder を独自の関数にネストし、2 回呼び出した後に次のビューに移動すると、はるかにクリーンになります。
ここでの答えのおかげで強制的に待機する方法を見つけました: Waiting for CLGeocoder to finish on concurrent enumeration
したがって、新しい方法は機能しますが、なぜ機能するのかわかりません。コードは次のとおりです。
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[gc reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error){
//do things
dispatch_group_leave(group);
}
//this is the confusing part!
while(dispatch_group_wait(group,DISPATCH_TIME_NOW)){
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0f]];
}
dispatch_release(group);
奇妙なことに、while ループを使用せずに次の操作を行うと、アプリがハングします。
dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
私がこれまでに読んだすべてのことを考えると、それはうまくいくはずですよね?
さらに紛らわしいことに、while ループ内では NSRunLoop が必要です。空の while ループを残して完全に削除すると、ループは際限なく繰り返されます。そのようです:
//this is the confusing part!
while(dispatch_group_wait(group,DISPATCH_TIME_NOW)){
//without NSRunLoop, this just goes on forever
}
while ループを正常に終了させるために NSRunLoop が行っていることは何ですか?