0

複数階建ての建物のデータを非同期にロードする 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]
    }
4

1 に答える 1

1

AppleGCDDocsのNSOperationQueue ...の使用を検討します

GCDはシステムレベルのアプリケーションに制限されていませんが、高レベルのアプリケーションに使用する前に、Cocoaで提供される同様の機能(NSOperationおよびブロックオブジェクトを介して)が使いやすいか、ニーズにより適しているかを検討する必要があります。詳細については、並行性プログラミングガイドを参照してください。

特にNSBlockOperationの使用を見てください。addExecutionBlock:を使用して、データに対する各リクエストを個別の実行ブロックに追加できます。次に、 setCompletionBlockを使用して完了ブロックを設定します。完了ブロックがメインスレッドで実行されていることを確認してください。

GCDを使用する必要がある場合は、グループを確認することをお勧めします

良い答えを持つstackoverflow関連の質問:

于 2012-12-27T16:51:43.413 に答える