0

現在、アプリを再起動できる機能をアプリに追加しています。

メインはこんな感じ

int main(int argc, char *argv[])
{
    const int RESTART_CODE = 1000;
    int return_from_event_loop_code;
    QPointer<QApplication> app;
    QPointer<foo> main_window;
    do
    {
        if(main_window)
            delete main_window; 
        if(app) 
            delete app;

            app = new QApplication(argc, argv);
            main_window = new foo();
            main_window->show();
            app->setActiveWindow(main_window);

            return_from_event_loop_code = app->exec();
    } 
    while(return_from_event_loop_code==RESTART_CODE);

  return return_from_event_loop_code;
}

ただし、以下の方法を使用してアプリケーションを再起動すると、初回は正常に実行RestartAppされます。の get メソッドはQNetworkAccessManagerロック エラーを返します。これは私のコードがどのように見えるかです

void foo::MethodA()
{
    ....
    ....
    QUrl url("some url");
    QNetworkRequest request;
    request.setUrl(url);
    networkManager = new QNetworkAccessManager(this);
    QObject::connect(networkManager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)),static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
    currentReply = networkManager->get(request); //Crashes when the app is restarted again
    connect(currentReply, SIGNAL(error(QNetworkReply::NetworkError)),this, SLOT(slotNetworkError(QNetworkReply::NetworkError)),Qt::UniqueConnection);
}

//Slot
void foo::replyFinished(QNetworkReply* rply)
{
    ....
    .....
    rply->deleteLater();
}

//Slot
void foo::RestartApp()
{
    QCoreApplication::exit(1000);
}

ここで、アプリが初めて起動したときに何が起こるかを示します。すべて問題ありません。ただし、RestartApp メソッドが呼び出され、return_from_event_loop_code = app->exec();今度は MethodA のステートメントで main のメソッドが再度呼び出されるとcurrentReply = networkManager->get(request);、アプリがクラッシュして終了します。

mlock.c

void __cdecl _unlock (
        int locknum
        )
{
        /*
         * leave the critical section.
         */
        LeaveCriticalSection( _locktable[locknum].lock );
}

アプリに再起動の指示が与えられたときに QNetworkAccessManager の get ステートメントでアプリがクラッシュする理由について何か考えはありますか?

4

1 に答える 1

0

事故について調べてみました。それは確かにの破壊によって引き起こされQApplicationます。QNetworkAccessManager内部でQNetworkConfigurationManagerPrivateオブジェクトを使用します。このオブジェクトは必要に応じて作成され、アプリケーションが終了するまで使用されます。このqNetworkConfigurationManagerPrivate関数は、既存のオブジェクトを作成または取得するために使用されます。

QApplication破棄されると、 を含むすべてのポスト ルーチンが実行されますconnManager_cleanup。この関数は間接的QNetworkConfigurationManagerPrivateにオブジェクトを破棄し、appShutdownローカル フラグを設定します。このフラグが設定されると、qNetworkConfigurationManagerPrivate関数は新しいQNetworkConfigurationManagerPrivateオブジェクトを作成しなくなります。したがって、破壊後はQApplication QNetworkAccessManager機能しなくなります。

オブジェクトの誤用だと思っていQApplicationましたが、最近、その使用が正しいことを証明するリンクを見つけました。

Qt のコーディング規約には次のように記載されています。

Q[Core]Application はシングルトン クラスです。一度に存在できるインスタンスは 1 つだけです。ただし、そのインスタンスを破棄して、新しいインスタンスを作成することができます。

したがって、この問題は Qt のバグと見なす必要があります。

于 2014-04-26T00:06:14.923 に答える