私はiOS用のopencvプロジェクトに取り組んでいます。キャプチャされて表示されたフレームを使用して開発を開始するための簡単なプロジェクトが与えられました。メモリの問題が発生し始め、元のプロジェクトのセットアップにまでさかのぼるまで、それがどのように機能するかについてあまり注意を払いませんでした. キャプチャ/表示コードを書き直す予定ですが、そもそもなぜそれが機能したのかわかりません。メソッドを呼び出す再生/一時停止ボタンがありました
- (IBAction)play_pause:(id)sender
{
play = !play;
while(play)
{
if (_videoCapture && _videoCapture->grab())
{
(*_videoCapture) >> _display_frame;
//process frame
self.imageView.image = [UIImage imageWithCVMat:_display_frame];
}
}
}
play は、アプリケーションが再生中か一時停止中かを示す単なるグローバル bool です。奇妙なことに、処理は無限ループ内で行われる必要があり、抜け道はありません。play がループ内で変更されることはありません。それにもかかわらず、アプリケーションが実行されているとき、再生/一時停止ボタンは応答性を維持し、再生ブールを反転して実行を一時停止することができます。それだけでなく、他のブール値 (use_greyscale など) は他のボタンで反転でき、その値はループ内で変化します。アプリケーションがフリーズし、新しいフレームを画面に描画することさえないと思っていました。アプリケーションは、その寿命のほとんどの間、その関数内に閉じ込められたままになり、描画や UIControl などの他のタスクを実行できなくなります。これが可能な唯一の方法は、IBAction 呼び出しが独自のスレッドで実行されている場合のようです。ソース コードにスレッド化の証拠が見つかりません。Apple が UI でスレッドを処理する方法を誰か説明できますか? メインの runloop スレッドは 1 つだけで、追加のスレッドは自動的に作成されないという印象を受けました。それが本当なら、この行動はどのように説明できますか?
サイドノート-
最終的にこれを調査したのは、[UIImage imageWithCVMat:_display_frame] が自動解放されたオブジェクトを返すことでした。これはすべてループ内で行われるため、実行を一時停止しないとオブジェクトを解放できず、クラッシュが発生していました。