[解決済み] Qtのシグナルとスロットについて、deleteとdeleteLaterはどのように機能するのですか?
質問
クラスQNetworkReplyのオブジェクトがある。そのfinished()シグナルに接続された(他のオブジェクトの)スロットがあります。シグナルは同期である(デフォルトのもの)。スレッドは1つだけです。
ある瞬間に、私は両方のオブジェクトを取り除きたいと思います。もうシグナルも何もありません。消したいのです。 そう思った私は
delete obj1; delete obj2;
しかし、本当にできるのでしょうか? QObjectの仕様にはこうあります。
保留中のイベントが配信されるのを待っている間にQObjectを削除すると、クラッシュが発生する可能性があります。
保留中のイベント」とは何でしょうか。
それは、私が私の
delete
を呼び出している間に、すでに配信されるべき「保留中のイベント」があり、それがクラッシュの原因となる可能性があり、実際に確認することができないということでしょうか?
では、私が呼び出したとしましょう。
obj1->deleteLater(); obj2->deleteLater();
安全のために
しかし、本当に安全なのか?その
deleteLater
は、制御がそこに到達したときにメインループで処理されるイベントを追加しています。に対して、保留中のイベント(シグナル)が存在する可能性があります。
obj1
または
obj2
はすでに存在し、メインループで処理されるのを待っています。
前に
deleteLater が処理されるのでしょうか?それは非常に残念なことです。私は、すべてのスロットで '多少削除された' 状態をチェックし、着信シグナルを無視するコードを書きたくありません。
どのように解決するのですか?
QObjectの削除は、2つの基本的なルールに従えば、通常は安全です(つまり、通常の実践では、私が知らない病的なケースもあるかもしれません)。
-
削除するオブジェクトからの (同期、接続タイプ "direct") シグナルによって直接または間接的に呼び出されるスロットまたはメソッド内でオブジェクトを決して削除しないでください。 例えば、シグナル Operation::finished() を持つクラス Operation があり、スロット Manager::operationFinished() がある場合、そのスロットでシグナルを発した Operation オブジェクトを削除しないようにします。finished()シグナルを発するメソッドは、シグナルを発した後も "this"にアクセスし続け(たとえばメンバーにアクセス)、無効な "this"ポインタで操作する可能性があります。
-
同様に、オブジェクトのイベントハンドラから同期的に呼び出されるコードでは、決してオブジェクトを削除しないでください。例えば、SomeWidget の SomeWidget::fooEvent() やそこから呼び出すメソッド/スロットの中で SomeWidget を削除しないでください。イベントシステムは、すでに削除されたオブジェクトに対して操作を続けます。
特に、複雑なシグナル/スロット チェーンがある場合、削除されるオブジェクトからのシグナルまたはイベントによって開始された削除が、いくつかのステップで発生する可能性があるため、どちらも追跡するのが難しい場合があります (POD メンバー変数にアクセス中にクラッシュするなど)。
このようなケースは、deleteLater()の最も一般的な使用例です。これは、制御がイベント ループに戻る前に現在のイベントを完了できることを確認し、イベント ループでオブジェクトを削除します。もう一つの、私はしばしばより良い方法は、キュー接続/QMetaObject::invokeMethod( ..., Qt::QueuedConnection ) を使用して全体のアクションを延期することだと思います。
関連
-
[解決済み] QDateTime::fromStringの使い方は?
-
[解決済み] Qtのフォームレイアウト機構を理解する
-
[解決済み] qtnetwork4.dllという正しいファイルが見当たりません。
-
[解決済み] qmake: ''の Qt インストールが見つかりませんでした。
-
[解決済み] QMLイメージの表示サイズを調整する
-
CMakeラーニングサマリー
-
[解決済み] QMake .pro ファイルで異なる Debug/Release 出力ディレクトリを指定する方法
-
[解決済み] QtCreatorのプロジェクトにサブディレクトリを作成するには?
-
[解決済み] Qt: *.pro と *.pri の比較
-
[解決済み] QComboboxから選択されたVALUEを取り出すにはどうしたらよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] QAbstractTableModelの内部にデータを設定する方法
-
[解決済み] qtnetwork4.dllという正しいファイルが見当たりません。
-
Qt signal and slot usage error : error: no matching function for call to ...... Qt signal and slot usage error : error: no matching function for call to ...... Qt signal and slot usage error: error
-
Qt: (クラス名)::connect()への呼び出しに一致する関数がない エラー概要
-
CMakeラーニングサマリー
-
[解決済み】Qt-Designerでレイアウトが自動拡張される。
-
[解決済み】QLabel: テキストと背景の色を設定する
-
[解決済み] Qt QuickとQt Widgetの比較 [終了しました]。
-
[解決済み] スロットに引数を渡す
-
[解決済み] QtCreatorとコマンドライン引数