Как стать автором
Обновить

Комментарии 8

В Qt при удалении объекта унаследованого от QObject автоматически отключаются сигналы связанные с ним.
Правильно, но это работает только тогда когда и владелец сигнала, и владелец слота принадлежат одному потоку. Это почти всегда верно в UI, и совсем не всегда верно в остальных частях проекта.

"Deleting a QObject while pending events are waiting to be delivered can cause a crash. You must not delete the QObject directly if it exists in a different thread than the one currently executing. Use deleteLater() instead, which will cause the event loop to delete the object after all pending events have been delivered to it."

http://doc.qt.io/qt-5/qobject.html#dtor.QObject
Прямое удаление через delete может привести к падению программы. Если удалять через deleteLater(), то безопасно. Вы ведь привели как раз эту цитату из документации.
Безопасное удаление через deleteLater может быть только в том случае, если этот метод каким-то образом гарантирует, что ни один асинхронный обработчик (в том числе, те, которые были вызваны после deleteLater!) не попадёт в очередь потока после удаления объекта. Пока я не вижу ничего об этом ни в документации, ни в коде.

Чуть позже почитаю код Qt более внимательно, и скажу, что я думаю по этому поводу.
All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue. However, it is often safer to use deleteLater() rather than deleting a QObject subclass directly.

doc.qt.io/qt-5/qobject.html#dtor.QObject
Перед удалением объект отключает соединения и удаляет из очереди все события к нему относящиеся.
Да, я как раз нашёл это в коде. Деструктор QObject действительно чистит очередь потока, в отличие от метода QObject::disconnect, который и ввёл меня в заблуждение.

Сейчас исправлю в статье.
Объект не может отключить себя от сигналов сам, что лично мне кажется нарушением инкапсуляции

http://doc.qt.io/qt-4.8/qobject.html#disconnect Почитайте документацию пожалуйста!!! Всё он может.
Я имел в виду, что он не может себя гарантированно отключить в своём деструкторе, а значит он должен либо подписываться на сигнал, который ему сообщит о том, что его хотят удалить, либо делегировать отписывание своему владельцу.

Сейчас, однако, я нашёл способ отписать объект не когда владелец захочет, а когда потеряется последняя владеющая ссылка на объект.
Для этого нужно использовать QSharedPointer с пользовательским deleter'ом.

http://doc.qt.io/qt-4.8/qsharedpointer.html#QSharedPointer-3

Статью поправлю, спасибо.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории