私は大きな問題を抱えていて、実際にそれを解決したと思っていました。QNetworkAccessManager を使用するアプリケーションがあります。この QNAM はクラス内にあります。この QNAM でリクエストを実行すると、それらはすべて、応答を保持し、ロジックを再試行するラッパーで実行されます。
たとえば、コンストラクターに putBlob (baseRequest から継承) がある場合、QNAM への参照を渡します。私はそれにリクエストを実行し、返信へのポインタを保存します。応答はラッパーの子になるため、QNAM はそれに対する所有権を失います。ラッパーは、QNAM を保持する元のクラスの子です。
クラスには QNAM と、子「QNetworkReply*」を持つ子「putBlobRequest」があります。
問題は、ユーザーがメイン オブジェクトとその中のすべてを削除するキャンセルを希望する場合です。ラッパーも QNetworkReply を中止して切断する必要があります (finish() を呼び出さないようにするため)。
baseRequest のデストラクタ (QNetworkReply を保持し、その親である) は次のようになります。
if(_reply) {
if(_reply->isRunning()) {
_reply->disconnect(SIGNAL(finished()));
_reply->disconnect(SIGNAL(uploadProgress(qint64, qint64)));
_reply->abort();
}
}
ラッパーを保持しているクラスでラッパーが強制終了されると、削除が行われます。(そうですか?)
これでうまくいくこともありますが、ときどき巨大なアクセス違反が発生し、次のコールスタックですべてがクラッシュします。
QtCored4.dll!QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method) Line 2891 + 0x8 bytes C++
QtNetworkd4.dll!QNetworkReplyImpl::abort() Line 874 + 0x18 bytes C++
FrameworkAzure.dll!BaseRequest::~BaseRequest() Line 129 + 0xa bytes C++
FrameworkAzure.dll!PutBlobRequest::~PutBlobRequest() Line 24 + 0x5e bytes C++
FrameworkAzure.dll!PutBlobRequest::`scalar deleting destructor'() + 0xb bytes C++
FrameworkAzure.dll!AzureBlobStorageProvider::~AzureBlobStorageProvider() Line 41 + 0xa8 bytes C++
したがって、最初に abort() が呼び出され、次が呼び出されます。
if (d->outgoingData)
disconnect(d->outgoingData, 0, this, 0); <--- we go in here
QOBject.cpp の 2891 行目に移動します。
const QMetaObject *smeta = sender->metaObject();
エラーでクラッシュする場所:
CloudSync.exe の 0x66c2c490 (QtCored4.dll) で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0xdddddddd。
アドレス「0xdddddddd」は「送信者」です。
送信者オブジェクトが読み取れないのはなぜですか? 私は何を間違っていますか?助けてください!
編集:
また試しました:
if(_reply) {
if(_reply->isRunning()) {
disconnect(_reply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
_reply->abort();
}
}
ここで、派生した putBlob の uploadProgress も切断します。切断せずに試してみましたが、「送信者」が違反しているという同じ問題がありました