2

事実:

バックグラウンドスレッドで実行するメソッドがあります:

[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];

このメソッドには基本的に、ユーザーが [終了] ボタンをクリックするまで実行し続ける while ループが含まれています。

-(void) playOn: (UIViewController*) thisViewController
{
    while(!quitButtonPressed)
    {
       // this is my method's main loop
    }
}

問題:

ユーザーが上記のループの途中で [Quit] をクリックする と、BOOL をもう一度チェックして最終的に停止する前に、残りのループを実行する必要があります。それが起こらないようにし、ユーザーが [Quit] をクリックするとすぐに while ループを停止させるために、while ループのあちこちに多くのループを追加して、半一定のチェックと「即時」の離脱を行うこともできると思います。必要に応じて。ただし、上記のメイン while ループのサイズと、多数の小さな while ループが含まれているという事実を考慮すると、設計の観点からは、これはあまり巧妙でも実用的でもないように見えます。 if(quitButtonPressed) break; その中に(if.. break;追加する必要がある数は非常に大きく、理解するのが非常に複雑になる可能性があります..)

可能な解決策(しかし、それは正しいものですか?)

したがって、ユーザーが [ Quit]をクリックした瞬間に、メソッド内の while ループ自体ではなく、上記のメソッドの while ループが実行されているバックグラウンド スレッドを停止/キャンセルするのが最善の方法であると考えていました。

これ、または同様のもの (つまり、より良い提案) は可能ですか?どうすれば正確にこれを行うことができますか?

上記の解決策の可能な実装:

この新しいメソッドを作成できます。

-(void)checkQuitButton
{
   while(!quitButtonPressed)
   {
      //wait
   }
   if(quitButtonPressed)
   {
     // stop this thread-->[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];
     // this is the method I'm looking for
   }
}

そして、次のように、2 つの別々のバックグラウンド スレッドで上記と前のメイン メソッドを同時に実行し始めることができます。

[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];
[currentGame performSelectorInBackground:@selector(checkQuitButton) withObject:nil];

ゲームの while ループが実行されている間、別のwhile ループが同時に QuitButton をチェックしています。しかし、ここで開始したことをキャンセルするために実際に呼び出すことができるメソッドはありますか?

[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];

?

4

1 に答える 1

6

正しい解決策は、「停止」フラグを定期的にチェックすることです。スレッドを突然終了しても、リソースをクリーンアップする機会はありません。要するに、あなたはひどくメモリをリークするでしょう。

しかし、より深い問題は、あなたがこの種のスレッドを持っているべきではないということです。間違ったデザインを強く示唆しています。NSOperationiOSでは、ほとんどのバックグラウンド操作は、Grand Central Dispatchを使用して、またはブロックを使用して実装された、集中的な操作の形式をとる必要があります。多くの異なる種類の機能を実行する長寿命のスレッドが必要になることはほとんどありません。操作内で、「キャンセルの確認」ステートメントをどこに配置するかはかなり簡単なはずです。

また、を使用する必要がある場合はほとんどありませんperformSelectorInBackground:。これは非常に危険な方法であり、ほとんど制御できません。代わりに、バックグラウンド操作を適切に実装する方法のガイダンスについて、並行性プログラミングガイドをお読みください。「スレッドからの移行」のセクションに特に注意してください。

于 2012-09-08T00:21:20.600 に答える