1

私のアプリには、多くの処理を実行するためのワーカースレッドがあります。処理中は、情報を使用してGUI要素を更新するメインスレッドに更新を送信します。これはで行われperformSelectorOnMainThreadます。コードを簡単にするために、これらの更新に制限はなく、高速(1秒あたり数百または数千)で送信されwaitUntilDoneますfalse。呼び出されるメソッドは、変数を取得して、それをViewControllerのプライベートメンバーにコピーするだけです。それらのいくつかはGUIを直接更新します(私が怠け者だからです!)。数秒に1回、ワーカースレッドはperformSelectorOnMainThreadwaitUntilDone設定して呼び出しますtrue(これは、現在の計算バッチの出力の保存に関連しています)。

私の質問:これは安全な使用法performSelectorOnMainThreadですか?バックグラウンドスレッドが問題なく動作し続けている(そして正しい出力を生成している)にもかかわらず、表示された値が更新を停止するという問題が最近発生したため、私は尋ねます。このように値が与えられるので、メッセージ数の制限に達したのではないかと思いました。私はすでに通常の容疑者(オーバーフロー、リークなど)をチェックし、すべてがきれいです。しかし、私は問題を再現することができませんでした。

4

1 に答える 1

1

コードを簡単にするために、これらの更新に制限はなく、高速で送信され(1秒あたり数百または数千)、waitUntilDoneはfalseです。

うん。そうしないでください。内部のみのアプリケーションでの怠惰のためでもありません。

メイン実行ループが応答しなくなる以外に、あらゆる種類の潜在的な問題が発生する可能性があります。

何よりも、メッセージが到着するのと同じ速さでUIを更新しようとしてメインスレッドが絶えず回転しているため、ワーカースレッドのCPUサイクルが不足します。描画がセカンダリスレッドで行われることが多いことを考えると、これによりスレッドの競合がさらに発生し、処理速度がさらに低下する可能性があります。

次に、これらのメッセージはすべてリソースを消費します。実装の詳細によっては、それらが多数存在する可能性があり、比較的不足している可能性もあります。

制限があるべきではありませんが、実際的な制限があると、それを超えると動作が停止する可能性があります。この場合、システムのバグになりますが、「メッセージが多すぎる、速すぎる、少なくなる」というコンソールログを超えて修正される可能性は低いです。

ただし、コードのバグである可能性もあります。スレッド間の状態の転送は、落とし穴に満ちた領域です。クロススレッド通信コードが防弾であると確信していますか?(そして、それが防弾である場合、それはあなたの数千/秒の更新通知のための莫大なパフォーマンスコストである可能性が非常に高いです)。

更新を抑制することは難しくありません。コメントされた提案はすべて合理的ですが、はるかに簡単に実行できます(NSNotificationQueueは素晴らしいですが、計算のさまざまな場所からメインスレッドを更新しない限り、やり過ぎになる可能性があります)。

  • メインスレッドに通知するたびにNSDateを作成し、日付をivarに格納します
  • 次回メインスレッドに通知するときは、N秒以上経過していないか確認してください
  • 持っている場合は、ivarを更新します
  • [ボーナスパフォーマンス]その日付の比較が高すぎる場合は、アルゴリズムを再検討して、「今すぐ更新」トリガーを頻度の低い場所に移動することを検討してください。それを除けば、int ivarカウンターを作成し、N回の反復ごとにのみ日付をチェックします
于 2013-03-25T15:41:16.890 に答える