2012-04-25 2 views
1

나는 내 앱이 하루 종일 충돌하는 이유를 찾으려고합니다. 수천 단어의 가치가있는 그림이므로이 코드를 살펴보십시오. 헤더 :충돌. QObject :: 정적 객체 인스턴스의 생성자에 연결

class SandboxedAppStat : public QObject 
{ 
    Q_OBJECT 

private slots: 
    void pidsTimerTimeout(); 

public: 
    QTimer m_PidsTimer; 

    SandboxedAppStat(QObject *parent = NULL); 
}; 

class SandboxedApp : public QObject 
{ 
    Q_OBJECT 

private: 
    static SandboxedAppStat SandboxedAppStat1; 
}; 

구현 :

내가 할 노력하고있어 실제로 무엇을
void SandboxedAppStat::pidsTimerTimeout() 
{ 
    qDebug() << "whatever"; 
} 

SandboxedAppStat::SandboxedAppStat(QObject *parent) 
    : QObject(parent) 
{ 
    bool b = QObject::connect(&m_PidsTimer, SIGNAL(timeout()), 
      this, SLOT(pidsTimerTimeout())); 
    m_PidsTimer.start(500); 
} 

SandboxedAppStat SandboxedApp::SandboxedAppStat1; 

, C++ 정적 생성자 동작을 시뮬레이션하는 것입니다. 내가 원하는

QObject::connect(&m_PidsTimer, SIGNAL(timeout()), 
     this, SLOT(pidsTimerTimeout())); 
m_PidsTimer.start(500); 

고정 멤버 SandboxedAppStat1이 초기화되는 즉시 호출 할 수 있습니다. 이것이 위의 코드가 SandboxedAppStat의 생성자에있는 이유입니다.

하지만, 내 문제는 내가 프로그램을 실행할 때, 그것은 즉시 오류 코드 C0000005 (I 추측 액세스 위반)으로 라인 connect(&m_PidsTimer, SIGNAL(timeout()), this, SLOT(pidsTimerTimeout()));

에 도달으로 충돌한다는 것입니다. 여기에 http://dl.dropbox.com/u/3055964/Untitled.gif

정적이 아닌 변수로 SandboxedAppStat를 선언하면 오류가없고 오류가 없습니다. 모든 것이 잘 작동합니다.

auto *t = this; 
QtConcurrent::run([&]() { 
    Sleep(3000); 
    bool b = QObject::connect(&(t->m_PidsTimer), 
     SIGNAL(timeout()), t, SLOT(pidsTimerTimeout())); 
    t->m_PidsTimer.start(500); 
}); 
:

먼저 나는 :: 그 다음 코드 왜 업데이트 SandboxedAppStat 생성자의, 호출 할 수 있도록 연결 충돌 이유는, 정적 멤버는 QObject를 위해 너무 일찍 초기화하고 있다는 사실이 될 수 있다고 생각

볼 수 있듯이 QObject :: connect는 정적 SanboxedAppStat가 초기화 될 때 3 초가 지나면 실행되지만 이것도 도움이되지 않습니다. 프로그램이 3 초 후에 중단됩니다.

저는 정말 혼란 스럽습니다. 나는이 문제의 원인이 무엇인지 이해하지 못합니다. 정적 객체 인스턴스에서 신호/슬롯을 사용할 수 있습니까?

내가 MSVC와 함께 2010 년 감사

UPDATE

을 Qt는 4.8.0를 사용하고 여기에 충돌을 재현 (HostileFork 제안으로) 하나의 헤더와 소스 파일로 구성, 간단한 프로젝트입니다. http://dl.dropbox.com/u/3055964/untitled1.zip

+0

이 코드가 컴파일 될 것으로 생각하지 않습니다. 이 줄을 보라 :'bool b = QObject :: connect (& m_PidsTimer), SIGNAL (timeout()), this, SLOT (pidsTimerTimeout()))'. 괄호는 잘 연결되어 있지 않습니다. – dschulz

+0

클래스 프로토 타입과 구현 파일을 포함하는 헤더 파일 인 최소한의 프로그램 예제를 작성해 보셨습니까? 나는 리눅스 4.8에서 그랬지만 충돌하지는 않았지만 디버그 출력에 QThread로 시작하지 않은 스레드에서 QTimer를 시작할 수 없다는 경고가있었습니다 (이는 아마도 이전에 타이머를 시작하려고했기 때문일 것입니다 QApplication 루프에 들어가기). – HostileFork

+0

@dschulz, 가능합니다. 여기에 붙여 넣을 때 코드를 제거 했으므로 실수를 할 수는 있었지만이 그림은 변경되지 않습니다. – Davita

답변

0

pidsTimerTimeout 슬롯을 정기적으로 방문 하시겠습니까? 아니면 건설 중에 한 번만 찾으십니까?

클래스가 생성 된 후에 신호를 받기만하면 연속 시간 초과가 필요하지 않은 경우 QTimer::singleShot 또는 QMetaObject::invokeMethod을 사용해보십시오. 모든 신호와 마찬가지로 단일 샷은 윈도우 시스템의 이벤트 대기열이 슬롯 실행에 약간 지연 될 수있는으로 처리 된 후에 만 ​​작동합니다.

MyClass::MyClass() 
{ 
    // Using a zero singles shot. 
    QTimer::singleShot(0, this, SLOT(initialized())); 

    // or using invoke method. 
    QMetaObject::invokeMethod(this, "initialized", Qt::QueuedConnection); 

} 

우리는 사무실에서이 코드를 사용하고 있으며 정적 객체를 사용하고 있습니다.

관련 문제