複数階建ての建物のデータを非同期にロードする iPad アプリを作成しています。すべてのフロアのデータロードが完了したら、ユーザーに警告するように NSNotifications を設定しました。
ChildViewController (ポップアップ VC) でロード ボタンが押されると、各フロアのデータ ロードがループで開始されます。
ChildViewController は ParentViewController から起動されます。
「dataloaded」という名前の通知用に ChildViewController にオブザーバーを追加し、通知を処理するためのハンドラー関数 childDataLoaded を設定します。
ChildViewController はデータのロードが完了する前に却下される可能性があるため、ParentViewController にオブザーバーとハンドラー (parentDataLoaded) をセットアップして、同じ「データロード済み」通知を処理します。
AppDelegate にデータ ロード関数 'parseAndSaveData' を実装しました。parseAndSaveData は、ChildViewController ボタンがクリックされると呼び出されます。パラメータとしてフロア識別子 (NSString) を取ります。Web サービスを呼び出してそのフロアのデータを取得し、このデータをデータベースにロードします。Web サービスは高速ですが、データを sqllite データベースに追加するには時間がかかります (コア データを使用しています)。したがって、dispatch_asynch 呼び出しを使用してこのデータロード部分を呼び出します (これが最も時間のかかる部分であるため)。
完了すると、データロード部分は「データロード済み」通知を送信します。
この通知は、ChildViewController または ParentViewController (通知が投稿されたときにアクティブな方) のいずれかのハンドラーを呼び出すことを期待しています。
私が抱えている問題は、通知が予測不可能であり、すべてのフロアが正常にロードされるという事実にもかかわらず、1 つのハンドラー (ChildViewController 内のハンドラー) のみが呼び出され、1 つのフロアに対してのみ呼び出されることです。
上記の設計と実装または代替案に関するアドバイスをいただければ幸いです。
@Samuel からの dispatch_group 提案のコードを追加
Confirm action on my popup VC kicks off the following…
creates a a GCD dispatch_group, floorDataGroup
creates a GCD dispatch_queue, floorDataQueue, using dispatch_get_global_queue
with default priority
loops over floors in building and for each floor {
dispatch_group_async(floorDataGroup, floorDataQueue, ^{
// start dispatch_group_async block
//gets rooms details for the building and floor as follows:
Calls webservice (using AFNetworking Library) to get room details,
which on success executes a block
( ^{
Parses the XML, extracts room data
Inserts room data into Core Data/sqllite table
}); //end web service success block
}); //end dispatch_group_async block
} //end loop over each floor
dispatch_group_notify(floorDataGroup, floorDataQueue, ^{
//start dispatch_group_nbotify block
create alert (UIAlert) with message “All floors loaded”
and an OK button to dismiss the alert
[alert show]
}