0

3 つのファイルに実装されているページ ビュー コントローラーがあります。そのうちの 1 つである ModelController.m は、「generateData」メソッドを実装します。これは基本的に、このページ ビュー コントローラーのすべてのページを構築してフォーマットするだけです。このメソッド内で最初に行うことは、「キャンセル」ボタンのあるプログレス バー ポップアップを作成することです。次に、while() ループ内でページを作成し続け、同時に 10 ページごとにプログレス バーを更新して、アプリケーションがまだ出力を生成していることをユーザーに確認します。

「generateData」メソッドが完了すると、つまり、すべてのページが構築されます (ユーザーの入力によっては、1,000 ページ以上または 10,000 ページになる場合もあります)。「self」が RootViewController.m 内のメソッドに返され、生成されたデータが渡されます。これにより、最終的にそのオブジェクト内のページがユーザーに表示されます。

「キャンセル」ボタンを除いて、すべてうまく機能します。「generateData」メソッドはメイン スレッドで実行されるため、ブロックされ、「キャンセル」ボタンがまったく反応しなくなります。もちろん、「ブロック」とは、すべての CPU サイクルが必要であり、他の処理を実行できないことを意味します。また、10,000 ページを生成するのに 1 分以上かかる場合があるため、ユーザーが操作をキャンセルできるようにしたいと考えています。

[キャンセル] ボタンを含むプログレス バー ポップアップ用に別のスレッドを作成しようとしましたが、すべての UI 操作をアプリケーションのメイン スレッドで実行する必要があるため、うまくいきません。

ほとんどうまくいくように見えるのは、「generateData」メソッドを別のスレッドに配置し、プログレスバーをメインスレッドに保持する場合です。これは問題なく動作しますが、「generateData」が別のスレッドに配置されてバックグラウンドで実行され、すぐに返されるため、空の「self」またはむしろ空の「dataObject」が返され、そのオブジェクトにはまだ何もないためクラッシュが発生します。表示する。

では、「generateData」スレッドが完了したかどうかを確認し、完了した場合にのみ「自己を返す」にはどうすればよいでしょうか? メインスレッドのループが再び「キャンセル」ボタンをブロックするため、実際には BOOL true/false 変数を使用してループで実行することはできません。

または、代わりに、iOS の長いメソッドで「キャンセル」ボタンを実装する正しい方法は何ですか? 多分私はそれをすべて間違っているかもしれませんが、私の人生では、これのための正しいレシピを見つけることができません.

事前に助けてくれてありがとう、コードはかなり広範であり、それが私が何も含めなかった理由ですが、私の説明が何が起こっているのかについての良いアイデアを与えることを願っています. それが役立つ場合は、コードを提供できます。

4

1 に答える 1