2012-12-12 14 views
19

Nowa składnia sygnałów i szczelin Qt5 pozwala nam na podłączenie sygnałów nie tylko do gniazd, ale także do zwykłych starych funkcji i funktorów/lambd. Problem polega na tym, że lambdy są niezbędnymi obiektami z operatorem(), a po podłączeniu do nich sygnałów są one kopiowane gdzieś w klasach wewnętrznych qt. A kiedy odłączysz sygnał od tego funktora, pozostanie on w wewnętrznych partiach qt. Nie rozumiem, czy to normalne zachowanie? A może istnieje sposób na zniszczenie tych obiektów funkcjonalnych po rozłączeniu?Qt5 nowy sygnał do wycieku pamięci połączeń lambda

Oto przykład:

//example 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    QTimer* timer = new QTimer(); 

    QSharedPointer<QMetaObject::Connection> connection(new QMetaObject::Connection()); 

    //functor is created and gets copied inside qt internals, connection variable is captured 
    //inside the functor 

    *connection.data() = QObject::connect(timer, &QTimer::timeout, [=] 
    { 
     qDebug() << "disconnected"; 
     QObject::disconnect(*connection.data()); 
    }); 

    timer->start(10000); 

    return a.exec(); 
} 

//example 

Teraz, kiedy patrzę na silne liczby referencyjnej zmiennej połączenie po odłączeniu gniazda, pozostaje 2, co oznacza, że ​​sam obiekt funktor jest wciąż żywy i dobrze, choć nie ma dla mnie teraz znaczenia. Czy coś mi brakuje?

+0

Co się dzieje, gdy zniszczy timer? –

+0

Taka sama myśl, ale liczba referencyjna nadal wynosi 2 =/ – Sigil

+0

Jedyny sposób, w jaki przechodzi do 1, jeśli nie przechowuję zmiennej połączenia w tej części "* connection.data() =" i usuń licznik czasu. Co nadal jest bardzo dziwne. – Sigil

Odpowiedz

7

Przykład jest zbyt zaawansowany (dlaczego używać QSharedPointer? Dlaczego przechwytywanie go przez wartość?). Ale rzeczywiście Qt przecieka obiekt funktora.

Chodzi o to, że lista połączeń wewnętrznych jest po prostu oznaczona jako zabrudzona i nie wyczyszczona, dopóki nie zostanie usunięty nadawca lub nie zostanie połączony nowy sygnał (zobacz zastosowania cleanConnectionLists).

podsunąłem kilka poprawek, które powinny rozwiązać ten problem: https://codereview.qt-project.org/#change,42976 i 42979

+1

Cóż, tak, wiem, że może wyglądać na nieco zbyt zaawansowanego, ale potrzebowałem tej wspólnej wskazówki, aby móc łatwo monitorować liczbę odniesień do niej, aby sprawdzić, czy obiekt funktora wciąż żyje, i mam prawdziwy projekt, w którym podobna logika nie znajduje się w głównej funkcji, więc nie mogę po prostu przechwycić połączenia przez odniesienie. – Sigil

Powiązane problemy