ここで自分の質問に答えているようです!実際のハードウェアでテストし、アプリストアに入れることができるようになるまで、回答を受け入れません. そうは言っても、どのオプションが機能しなかったかなど、最新の情報をここに残しておきます。
アイデア #1 : 各 NSRunLoop はスレッド固有であることが判明しました。別のスレッドで UIApplicationMain を作成すると、メッセージが表示されません。副作用として、これにより初期化がいつ終了したかを判断できなくなります。そのため、スレッドセーフではない何かがある場合、それは機能しません。スレッド間でメッセージを送信して、いつ初期化が終了したかを把握できるかもしれませんが、今のところ、これを行き止まりと呼んでいます。
アイデア #2 : UIApplicationMain は多くの微妙なことを行います。何が制限されているのかわかりませんが、UIApplicationMain を使用しないと何も機能しませんでした。アイデア#2はすぐに出てきました。
アイデア #3 : OS シグナルの受信は重要です。通話オーバーレイがあるかどうか、または終了しようとしているかどうかを知る必要があります。その上、セットアップ メッセージのいくつかは、アプリを適切に起動するために不可欠なようです。UIApplicationMain 内にいなくてもメッセージを送信し続ける方法を見つけることができませんでした。私が思いついた唯一のオプションは、NSRunLoop と CFRunLoop でした。どちらも機能しませんでした - メッセージは私が望んでいたようには届きませんでした。私はこれらを正しく使用していないかもしれませんが、いずれにせよ、アイデア #3 が出ています。
まったく新しいクレイジーなアイデア #4 : setjmp/longjmp を使用して、C/C++ でコルーチンを偽造することが可能です。トリックは、最初にスタック ポインターを重要なものを壊さない値に設定し、次に 2 番目のルーチンを開始してから、スタックが 2 つあるふりをして前後にジャンプすることです。「2 番目のコルーチン」がメイン関数から戻ることを決定した場合、事態は少し混乱しますが、幸いなことに、UIApplicationMain は決して返らないため、これは問題ではありません。
実際のハードウェアでスタック ポインターを明示的に設定する方法があるかどうかはわかりません。たとえば、その場で割り当てたデータのチャンクに設定する方法はありません。幸いなことに、それは問題ではありません。iPhone にはデフォルトで 1MB のスタックがあり、いくつかのコルーチンを簡単に収めることができます。
私が現在行っていることは、alloca() を使用してスタック ポインターを 768 キロバイト先にプッシュし、次に UIApplicationMain を生成し、setjmp/longjmp を使用して「UI ルーチン」と「メイン ルーチン」の間を行ったり来たりすることです。これまでのところ、これは機能しています。
警告:
「UI ルーチン」に処理するメッセージがない場合を知ることは不可能であり、処理するメッセージがない場合は、それがなくなるまで無期限にブロックされます。0.1ミリ秒ごとにトリガーするタイマーを作成することでこれを解決しています。タイマーがトリガーされるたびに、「メイン ルーチン」に戻り、1 つのゲーム ループを実行してから、「UI ルーチン」に戻って別のタイマー ティックを行います。ドキュメントを読むと、「タイマー呼び出し」が無限に積み重ならないことがわかります。「終了」メッセージを適切に取得しているようですが、まだ完全にテストすることはできておらず、他の重要なメッセージもテストしていません。(幸いなことに、合計 4 つのメッセージしかなく、そのうちの 1 つはセットアップ関連です。)
最近のほとんどの OS は、スタック全体を一度に割り当てることはありません。iPhoneはおそらくその1つです。私が知らないのは、スタック ポインターを 3/4 メグ前方にバンプすると、いわば「その後ろ」にすべてが割り当てられるかどうかです。もしそうなら、私は事実上 4 分の 3 メガの RAM を浪費している可能性があり、これは iPhone ではかなりの量です。これは、ポインタを少しだけ前方にバンプすることで処理できますが、これは実際にはスタックサイズの災害を助長します.スタックを事実上、ポインタを前方にバンプするだけに制限するため、事前にこれを把握する必要があります. スタック内のいくつかのセンチネル データと、適切な監視およびスタック サイズの問題のログ システムを組み合わせることで、おそらくこれを解決できますが、これは重要な問題です。(または、スタック ポインターをネイティブ ハードウェアで直接いじる方法がわかれば、malloc()/new[] 数キロバイトをスタック ポインターでポイントし、それを新しいスタックとして使用するだけです。どのくらいのスペースが必要かを把握する必要がありますが、あまり機能していないことを考えると、それほど多くはないと思います。)
これは現在、実際のハードウェアでテストされていません (1 週間か 2 週間待ってください。最初に別のプロジェクトを完成させる必要があります)。
Apple が私が何をしているのかを把握し、App Store に提出しようとしたときに巨大な REJECTED ステッカーを貼るかどうかはわかりません。これは、API に対する彼らの意図からわずかに外れていると言えます。成功を祈っている。
この投稿を更新し続け、機能することを確認したら、正式に受け入れます。
更新が遅くなりました: 他にもいろいろと気を散らしてしまいました。それ以来、私はいくつかの変化を経験してきたが、その結果、Apple の開発にはあまり興味がなくなった。私の現在のアプローチはうまくいかない兆しを見せていませんでしたが、それを肉付けし続ける動機は本当にありません. ごめん!気が変わったら、これをさらに更新しますが、Outlook はあまり良くありません。