4

method1サーバー(POST)に非同期要求を行って、指定されたIDでCommunicationLinkオブジェクトを作成するメソッド(呼び出します)があります。このメソッドは、要求を送信する前に、CommunicationLinkがサーバー上にすでに存在するかどうかを確認します。

特定のCommunicationLinkIDに関連付けられた「トピック」オブジェクトのリストをフェッチする2番目のメソッド(method2と呼びましょう)があります。と同様method1method2、CommunicationLinkがサーバー上にすでに存在するかどうかを確認し、存在しない場合は作成します(ここでも、サーバーに非同期要求を送信します)。

私が抱えている問題は、アプリケーションを起動すると次々と呼び出されるため、次のようになってしまうことですmethod1method2

method1 checks if CommunicationLink exists ---> NO
  method1 sends a request to create CommunicationLink (async call)

method2 checks if CommunicationLink exist ---> NO because the previous call is not done yet
  method2 sends a request to create CommunicationLink

  method1 done
  method2 done

したがって、サーバーでは、同じIDに対して2つのCommunicationLinksになります(サーバー側で何が起こっているかを制御することはできません)

すでにサーバーにリクエストを送信しているmethod2場合、「一時停止」するための最良の方法は何でしょうか。コールインの前にmethod1ブール値を設定し、リクエストが完了してinを取得したら、ブール値に戻すことができますが、これを行うにはもっと良い方法があると感じています。truemethod1falsewhile (!myValue);method2

編集

このコードは、プッシュ通知を処理するために作業している静的ライブラリの一部である場合。ライブラリを使用するテストアプリにも取り組んでいます。method1が呼び出され- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken;method2ルートビューで呼び出されます。viewDidLoad

方法1

- (void)sendProviderDeviceToken:(NSData *)deviceToken contextUUID:(NSString *)contextUUID sourceUUID:(NSString *)sourceUUID topicUUID:(NSString *)topicUUID language:(NSString *)language;

CommLinkを作成するメソッド

- (void)createCommunicationLinkWithSuccessHandler:(void (^)(NSNumber *))successHandler errorHandler:(void (^)(NSError *))errorHandler;

方法2

- (void)retrieveSubscriptionForContext:(NSString *)contextUUID notificationTopic:(NSString *)notificationTopic completion:(void (^)(NSDictionary *))completion;

このケースをライブラリで直接処理できるようにしたいので、テストアプリを変更する必要はありません。method1method2同じスレッドで呼び出されます。

ありがとう

4

3 に答える 3

2

ここでの主なポイントは、あなたがどのように対処しているかです。

「method1はCommunicationLink(非同期呼び出し)を作成するための要求を送信します」

そこにある種のコールバックを提供する必要があります。次に、コールバックは2番目のステップを実行/トリガーします。

NSURLResponse / Connectionまたは他のネットワークフレームワーク(AFNetworkingなど)を使用している場合は、そのような種類のコールバックメカニズムを利用できます(これは、デリゲートメソッド、またはネットワーク要求に渡す完了ブロックの形式を取ります) 。詳細については、詳細をお知らせください。

もう1つのアプローチは、ワークフローmethod1 / method2を別のスレッドで管理することです。これにより、UIをブロックせずに待機できますが、これははるかに複雑になります。

編集:

あなたはあなたを使うことができます

(^)(NSNumber *))successHandler

method2の実行を連鎖させるためのmethod1への引数。

または、次のようにできます。

  1. 実行時にmethod1、アプリが応答を待機していることを示すフラグを設定します。

  2. 応答を受信したら(つまり、insuccessHandlerまたはerrorHandler)、フラグをリセットします。

  3. viewDidLoad、実行する前method2に、フラグのステータスを確認しmethod2、応答を待っていない場合にのみ実行します。

デリゲートとViewControllerの両方からアクセスできるある種のステータス情報を作成する必要があります。

それが役に立てば幸い。

編集2:

最初のネットワーク要求が完了する前にViewControllerをロードできるという事実を考慮に入れるために、私はこれを提案します:

  1. ネットワーク要求とそのさらなる処理を除外します(そのためviewDidLoad、ネットワーク要求の内部と外部からそれらを呼び出すことができます)。method2viewDidLoad

  2. 上記で定義したメソッドをNSNotificationCenter通知のオブザーバーとして登録します。

  3. viewDidLoad、method1ネットワーク要求がまだ進行中の場合は、ステップ1で定義されたメソッドを呼び出さないでください。

  4. method1アプリの代理人から電話をかけるときは、successHandler投稿に通知を送信して、最初の接続が確立されたことを関係者に知らせます。

    4b。手順2で登録された通知オブザーバーのおかげで、ビューコントローラーはその状態を更新できるようになります(最終的にはを呼び出すことができますmethod2)。

これには、アプリにいくつかの変更が必要になります。つまり、View Controllerは「オフライン」モードをサポートする必要があります。このモードでは、method2ネットワークがない、応答を待っている、応答がないなど、全体的な状態に応じて実行およびユーザーに情報を表示できません。

于 2013-02-27T15:13:28.453 に答える
1

2番目のメソッドを実際に待機する必要がない場合は、KVOがこれを行うための便利な方法です。オブジェクトのプロパティまたは別のオブジェクトがで変更されるのをオブジェクトに待機させますobserveValueForKeyPath:ofObject:change:context:

于 2013-02-27T14:57:51.657 に答える
0

もちろん、最善の方法はミューテックスを使用することです。これは、この種の問題の標準的なアプローチです。

pthreadミューテックスまたはディレクティブのいずれかを使用できます@synchronized(アップルのスレッドプログラミングガイドを参照してください)。

于 2013-02-27T14:54:26.870 に答える