2012-05-14 3 views
4

3 가지 신호를 방출하는 물체가 있는데이 신호를 전송할뿐 아니라 발신자를 삭제하고 싶습니다. 이 객체는 이러한 객체의 이미 터 역할을하는 다른 객체에 있습니다.별도의 슬롯에서 발신자를 삭제하십시오.

Usally 나는이처럼하는 방법 것 :

void SomeClass::someSideFunction() { 
    Request* request = _StorageProvider.insert("somedata"); 

    connect(request, SIGNAL(succeded()),  this, SLOT(handleSucceded())); 
    connect(request, SIGNAL(failed()),   this, SLOT(handleFailed())); 
    connect(request, SIGNAL(alreadyExists()), this, SLOT(handleAlreadyExists())); 
} 

void SomeClass::handleSucceded() { 
    Request* request = qobject_cast<Request*>(sender()); 
    if(request != NULL) request ->deleteLater(); 
    emit succeded(); 
} 

void SomeClass::handleFailed() { 
    Request* request = qobject_cast<Request*>(sender()); 
    if(request != NULL) request ->deleteLater(); 
    emit failed(); 
} 

void SomeClass::handleAlreadyExists() { 
    Request* request = qobject_cast<Request*>(sender()); 
    if(request != NULL) request ->deleteLater(); 
    emit alreadyExists(); 
} 

이 일을 더 나은 방법이 있나요? "request"가 storageProvider의 자식이지만, 부모가 죽을 때까지 삭제를 기다리는 많은 요청을 처리하는 방법이 있습니다.

나는 다음과 같은 솔루션의 어떤 종류의 생각 : 존재하는 경우

connect(request, SIGNAL(succeded()),  this, SIGNAL(succeded())); 
connect(request, SIGNAL(failed()),   this, SIGNAL(failed())); 
connect(request, SIGNAL(alreadyExists()), this, SIGNAL(alreadyExists())); 
connect(request, SIGNAL(succeded()),  this, SLOT(memoryHnadler())); 
connect(request, SIGNAL(failed()),   this, SLOT(memoryHnadler())); 
connect(request, SIGNAL(alreadyExists()), this, SLOT(memoryHnadler())); 

메모리 핸들러가 보낸 사람을 제거 할 경우. 이 접근 방식의 단점은 무엇이며 더 나은 점은 무엇일까요?

개체는 완료되면 이러한 신호 중 하나만 방출합니다.

답변

2

두 번째 방법에 대한 단점은 없습니다. Qt는 먼저 신호를 보내고 나중에 메모리 핸들러를 호출합니다. 연결을 선언 할 때와 같은 순서로 실행됩니다.

메모리 핸들러 만이 Request 개체를 삭제해야합니다.

또 다른 접근법은 Request 개체를 인수로 사용하여 신호를 방출 한 다음이를 삭제하기 위해 사용자 슬롯에 의존하는 것입니다. 그러나 사용자 슬롯이 선언되지 않으면 메모리가 계속 증가하게됩니다 ...

+0

수신자 슬롯에서 보낸 사람 개체를 삭제할 수 없습니다. 대부분의 경우 제어가 보낸 사람에게 다시 전달됩니다. 삭제 한 사람은 정의되지 않은 동작 영역입니다. (deleteLater를 사용하지 않는 한 첫 번째 접근법이 더 짧고 슬롯이 적습니다.) – Mat

+0

물론, 삭제자를 삭제하려는 경우 슬롯에서 삭제를 호출해야하며 항상 삭제해야합니다. –

+0

사실 이러한 개체가 무언가에 영향을주는 요소가 될 것입니까? 나는 그들을 여기에서 지울 수있을 것이고, 부모가 그 아이들을 죽일 때,이 권리를 찾지 못할 것입니까? – chikuba

3

옵션은 QObject :: deleteLater()를 사용하여 요청을 자체 예약하도록 예약하는 것입니다. 이처럼 (명시 적) (거짓 setAutoDelete를 통해 해제하지 않는 한) 예를 들어

void Request::emitSucceeded() { 
    emit succeeded(); 
    deleteLater(); 
} 

void Request::emitFailed(int errorCode, const QString& errorString) { 
    m_errorCode = errorCode; 
    m_errorString = errorString; 
    emit failed(); 
    deleteLater(); 
} 

, 비동기 작업에 대한 KDELib의 기본 클래스, KJob는이 패턴을 사용하고 있습니다.

관련 문제