Название: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: voronElf от Декабрь 15, 2009, 08:38 Всем привет.
При использовании QNetworkAccessManager при финише запроса мы получаем объект ответа QNetworkReply. Создает этот объект QNetworkAccessManager и выдает его адрес, а вот насчет удаления этого объекта документация говорит, что удалять нужно ручками самому в коде. Хочу обсудить вопрос: в каком месте кода его удалять (не в конкретной програме, а в принципе) ? Пробовал удалять в слоте, обрабатывающем сигнал finished(...) от QNetworkAccessManager. Нормально отрабатывает, проблема только в одной ситуации: используем прокси (QNetworkProxy) и если уходил запрос с неправильным логином(паролем) пользователя прокси (код статуса 407, ошибка 105 QNetworkReply) то прога вылетает по обращении недоступной памяти. Если не удалять совсем, почистит ли Qt память с этого объекта по завершению приложения ? экспериментировал на Qt 4.5.2 PS: Я понимаю, что можно запонинать адреса объектов QNetworkReply и грохать потом в месте кода, где уже гарантированно соединения завершены. Но это уже от конкретного кода зависит, а хотелось бы какой-нибудь унифицированный вариант придумать. Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: Dendy от Декабрь 16, 2009, 23:08 В документации написано, что у QNetworkReply родителем ставится автоматически экземпляр QNetworkAccessManager, значит, что при удалении последнего удалятся и все запросы. Ещё посмотрите в сторону QObject::deleteLater(). Вообще удалять обьекты прямо в слотах опасно, так как обьект, испустивший сигнал, может на следующей строчке обратиться к этому удалённому экземпляру. Нужно смотреть каждый случай в отдельности.
Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: voronElf от Декабрь 17, 2009, 11:27 Ну вот видимо при ситуации с прокси испустивший сигнал объект и обращается к уже удаленному. Покопаю в сторону QObject::deleteLater().
Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: Dendy от Декабрь 17, 2009, 11:36 Рекомендую делать: reply->abort(); reply->deleteLater(). Первое по идее заблокирует дальнейшее использование, чтобы на следующей строчке испускающий сигнал код мог проверить его состояние. Второе - прибьёт reply на следующей итерации главного цикла. Вообще в коде Qt встречается подобное:
Код
Но каждый случай должен быть документирован отдельно, что можно, а что нельзя удалять в слотах. Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: voronElf от Декабрь 18, 2009, 10:48 Потестил (на ситуации с проксей) , достаточно одного reply->deleteLater(), вылетаний памяти уже нет (все таки очищается очередь событий к удаляемому объекту). Но надежнее конечно сначала делать явный reply->abort(). Я ж не абсолютно все ситуации протестил )))
Удалять в слотах конечно способ опасный (документация еще пишет о проблемах QObject::deleteLater() с новыми циклами событий). Но думаю для схемы работы QNetworkReply способ вполне применим. Буду использовать abort() и deleteLater(). P.S. Спасибо за комментарии Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: jjoss от Декабрь 20, 2009, 19:13 Столкнулся с подобной проблемой.
Делаю так. Код: class ODSSCon : public QObject Затем: Код: .... И в слоте finishedReadReply() делаю currentReply->deleteLater(); Так же реализован пример QT $QT_DIR\examples\network\downloadmanager\. Подряд делаю 2 запроса. В итоге, получаю данные только второго. Куда смотреть? Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: Dendy от Декабрь 21, 2009, 03:10 Каждый запрос должен ложиться в отдельную переменную.
Название: Re: Использование QNetworkAccessManager. Где удалять QNetworkReply ? Отправлено: kataklysm от Ноябрь 10, 2010, 15:05 Каждый запрос должен ложиться в отдельную переменную. Столкнулся с такой же проблемой. Не подскажите как можно реализовать такое, при этом их n-количество. Спасибо. |