2011-12-14 39 views
2

HTTPリクエストの応答を処理するためにコールバックメソッドをオーバーライドしています。非同期呼び出しを同期化する方法

-(NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path{ 
    NSObject <HTTPResponse> *response; 
    // Here I should load the data 
} 

しかし、私の要求に私は非同期に動作するいくつかのデータをロードする必要があります:私はsynchonous方法にしていますので

- (void)assetForURL:(NSURL *)assetURL resultBlock:(ALAssetsLibraryAssetForURLResultBlock)resultBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock; 

、私はメソッドを持って前に、「残す」ことができませんデータ。また、私が要求に入るまでに必要な資産がわからないので、必要なデータを事前にロードすることはできません。

これは私にとって非常にトリッキーなデザイン問題であると思われ、私はいくつかの大きなハックがなければこれを解決する方法を見つけることができません。

+2

あなたのHTTP要求を同期させるオブジェクトを変更することはできますか? HTTP要求は決して同期してはいけません。 これを行うことができず、実際にこれを解決する必要がある場合は、要求が完了するまで実行ループを作成して実行することができます。しかし、私はこれがあなたが(正しい)避けようとしている「主要なハッキング」カテゴリに入ると考えています。 – stevex

+0

@stevex HTTPコールを非同期で行うことができるかどうかを調べる必要があります。たとえそれがハッキーであったとしても、私はどのように "待機ループ"をしなければならないかを示すことができます。私は前に同じ問題を抱えていましたが、デリゲートのコールバックに時間がかかります(それはメインスレッドにもないかもしれません)ので、例が便利で、どうやってそれを行うのか分かりませんそれらのブロック。 – Besi

答えて

5

EDIT:stevexは、すべてのことを非同期にする方法を見つけることが最優先事項であるはずです。それに失敗すると、下記の答えは、最適な電力使用のために同期手順をOSに委ねながら、あなたが望むものを達成するはずです。

おそらくNSConditionLockを使用して、コール直後にassetForUrl:...を呼び出したものをロックし、コールバックでロックを解除したいとします。

条件ロックは条件付きのロックです。つまり、条件がXのときにロックを欲し、その状態になるまでスレッドがブロックされます。ロックを解除してロックを解除すると、ロックが解除された直後の状態を指定することができます。

条件はNSIntegersで指定します。

したがって、ロックに組み込まれた通信の側面があります。例えばので

、:

NSConditionLock *conditionLock; // somewhere; an instance variable 

#define kYourClassInitialCondition 0 
#define kYourClassWaitingCondition 1 
// etc 

... 

[conditionLock lockWhenCondition:kYourClassInitialCondition]; 

[whomever assetForUrl:whatever 
      resultBlock:^(args here) 
         { 
         ... do relevant immediate work here ... 

         [conditionLock lockWhenCondition:kYourClassWaitingCondition]; 
         [conditionLock unlockWithCondition:kYourClassFinishedCondition]; 
         } 
      failureBlock:^(args here) 
         { 
         ... as above, same semantics when done ... 
         } 
]; 


[conditionLock unlockWithCondition:kYourClassWaitingCondition]; 

[conditionLock lockWhenCondition:kYourClassFinishedCondition]; 
[conditionLock unlockWithCondition:kYourClassInitialCondition]; 

ので、呼び出し元のスレッド上のロジックは次のとおりです。

  • URLが要求
  • リリースをフェッチ初期条件
  • 問題でロックを取得待機状態のロック
  • 完成状態のロックを取得
  • 結果ブロックの初期条件

とロジックでロックを解除することである:

  • が待機状態に
  • リリース完成した状態でロックをロックを取得

呼び出しブロックが条件ロックを待機状態にするまで、結果ブロックはブロックされます。したがって、コールバックが即時である場合はシーケンス処理に問題はありません。

待機状態を確立した後、終了状態で条件ロックが解除されるまで、呼び出しスレッドはブロックします。したがって、すでに完了していない場合、結果ブロックが完了するのを待つ必要があります。

これは、もちろん、結果ブロックが呼び出し先によってGCDによってディスパッチされること、またはインラインが別のスレッドから呼び出されたと想定していることを前提としています。前者はおそらく安全な前提です。

関連する問題