2011-02-07 6 views
9

-[NSRunLoop runUntilDate:]に電話するのは良い考えですか?それは何の問題もなく動作するようですが、実行ループ内から実行するように実行ループに指示するのは緊張しています。- [NSRunLoop runUntilDate:]を呼び出すのがいいですか?

さらに詳しい情報:

私は今のプロジェクトを持っていることは、RESTサービスからデータをフェッチしています。入手が必要な重要な情報の1つは、有効なデータを持つ日付の範囲です。これは一度だけ取得する必要がある非常に小さなデータですので、ローカル変数がnilの場合は、プロパティをデータにダウンロードさせることをお勧めします。私はASIHTTPRequestASINetworkQueueを使用していますので、デフォルトではすべてが非同期であり、これを機能させるには、データがダウンロードされて処理されるまでこのプロパティを返すことができません。ここに私のコードの概要ですが、変数の名前は無実を保護するために変更されました:

__block BOOL isWorking = YES; 
__block ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:/*actual URL*/] autorelease]; 
[request setCompletionBlock:^{ 
    // set local variable 
    isWorking = NO; 
}]; 
[request setFailedBlock:^{ 
    // show alert to user 
    isWorking = NO; 
}]; 
[queue addOperation:request]; 

while (isWorking) { 
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 
} 

は繰り返しますが、これは正常に動作しているようです。このアプローチを使用する際に潜在的な問題はありますか?

答えて

3

オーバーラップしているコールツリーが完全にリエントラントでない限り、呼び出す実行ループによって呼び出される可能性のあるメソッドからこれを行わないようにする必要があります。

Cocoa TouchのUIコードはリエントラントとして記載されていません(Apple DTSからの警告/ヒントはありません)。したがって、フェッチデータハンドラをUIメソッド(またはUI実行ループで呼び出すことができる他の非リエントラントコード)、内部からUI実行ループを呼び出すことはお勧めできません。

+0

ので、この場合には、それが聞こえますこのプロパティはデータのダウンロード中に使用中です。しかし、ユーザーが忙しい間にボタンを押してそのプロパティを再度呼び出すことができた場合、それは爆発するだろうか?知っておいてよかった。 –

+0

このプロパティは、UIメソッドまたはデリゲートによって直接的または間接的に使用されますか?もしそうなら、それはまだ大きな問題です。 – hotpaw2

+0

私はUIがユーザーに提示される前に、アプリケーションが最初に読み込まれるときにこのコードが一度しかヒットしないだろうと確信しています。その後、データはそこにあり、ローカル変数を使用します。何らかの理由でデータをダウンロードできない場合は、ユーザーにモーダルアラートを表示し、正常にダウンロードされるまでアプリに入ることはできません。 –

4

ネットワークコードからの非同期完了イベントに応答して、何らかの種類のスピナーを表示して切り捨てる方が良いですか? Like:

​​

これは、実行ループでのモンキーよりも優れていると考えられます。しかし、あなたはすでにこれを知っていて、runloopソリューションには正確な欠点があることを知りたいことがあります。


あなたは値の準備ができるまでブロックしたい場合は、セマフォを使用することができます。この方法は安全であるように呼び出すことができます他に何もないので、

dispatch_semaphore_t sem = dispatch_semaphore_create(0); 
[request setCompletionBlock:^{ 
    dispatch_semaphore_signal(sem); 
}]; 
[queue addOperation:request]; 

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 
dispatch_release(sem); 
+0

デリゲート/コールバックメソッドのアプローチが可能だった場合、これが私がとるアプローチです。この場合、プロパティから返される前に値を設定する必要があります。そうしないと、アプリケーションで不良データが継続されます。デザインパターンが機能するように、コードをリファクタリングすることができました。この質問は、私がまだ見ていないという私のアプローチで予期しない問題が起きる可能性があるかどうかを知ることです。 –

+0

セマフォのアプローチがメインスレッドをブロックしないでしょうか?ブロックの実行を妨げないでしょうか? –

+0

使用するHTTPライブラリの実装方法によって異なります。はい、メインスレッドがブロックされるので、ライブラリがメインスレッドを使用する場合はセマフォを使用できません。 – zoul

関連する問題