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();这次currentReply = networkManager->get(request);在 MethodA 中的语句中再次调用 main 中的方法时,应用程序崩溃并最终在

mlock.c

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

当应用程序收到重启指令时,为什么应用程序在 QNetworkAccessManager 的 get 语句中崩溃?

4

1 回答 1

0

我已经对坠机事件进行了一些调查。确实是破坏造成的QApplicationQNetworkAccessManager内部使用一个QNetworkConfigurationManagerPrivate对象。该对象在需要时创建并使用,直到应用程序完成。该qNetworkConfigurationManagerPrivate函数用于创建或获取现有对象。

QApplication被销毁时,它会执行所有的 post 例程,包括connManager_cleanup. 此函数间接销毁QNetworkConfigurationManagerPrivate对象并设置appShutdown本地标志。设置此标志后,qNetworkConfigurationManagerPrivate函数将不再创建新QNetworkConfigurationManagerPrivate对象。所以破坏之后QApplication QNetworkAccessManager就变得不起作用了。

我认为这是对对象的滥用QApplication,但最近我发现了一个使用正确的证明链接。

Qt 的编码约定规定:

Q[Core]Application 是一个单例类。一次只能有一个实例。但是,可以销毁该实例并创建一个新实例。

所以这个问题应该被认为是一个Qt错误。

于 2014-04-26T00:06:14.923 回答