0

ネットワーク アクティビティが別のスレッドで行われるアプリがあります (ネットワーク スレッドは継続的にサーバーからデータを取得し、ディスプレイを更新します - ディスプレイの呼び出しはメイン スレッドで行われます)。ユーザーがログアウトすると、メイン スレッドは次のようにネットワーク スレッドで切断メソッドを呼び出します。

[self performSelector:@selector(disconnectWithErrorOnNetworkThread:) onThread:nThread withObject:e waitUntilDone:YES];

このセレクターはほとんどの場合呼び出され、すべて正常に動作します。ただし、この呼び出しが返されない (つまり、セレクターが実行されない) 場合があり (おそらく 10 回のうち 2 回)、スレッドとアプリがハングするだけです。performSelector が不規則に動作する理由を知っている人はいますか?

呼び出しが実行されるまで待つ必要があることに注意してください。そのため、waitUntilDone が YES になっているため、それを NO に変更することはできません。また、ネットワークスレッドには実行ループが実行されています(スレッドの作成時に明示的に開始します)。

また、データ転送は継続的に行われるため、GCD やオペレーション キューではなく、NSThreads を明示的に使用する必要があることにも注意してください。

4

1 に答える 1

3

次の場合にハングします。

  • メソッドが呼び出されたのと同じスレッドでセレクターを実行しようとしています

  • セレクターを実行するための呼び出しは、実行セレクターをトリガーした同期呼び出しが行われたスレッドに対するものです。

プログラムがハングしたら、すべてのスレッドのバックトレースを調べてください。

あらゆる種類のネットワーク同時実行を実装する場合、一般に、ネットワーク コードから UI レイヤーまたは他のスレッドへの同期呼び出しを行うことは非常に悪いことに注意してください。ネットワーク スレッドは非常に応答性が高い必要があるため、メイン スレッドをブロックすることが悪いのと同様に、ネットワーク スレッドをブロックできるものもすべて悪いものです。

また、コールバックを使用する一部の API では、コールバックが配信されるスレッドが必ずしも保証されないことにも注意してください。説明されているように、これにより断続的なロックアップが発生する可能性があります。

最後に、アクティブなポーリングを行わないでください。なんらかのイベントが到着しない限り、ネットワーク スレッドは完全に静止している必要があります。あらゆる種類のループ ポーリングは、バッテリー寿命と応答性に悪影響を及ぼします。

于 2012-11-05T21:34:47.293 に答える