![]() |
|
| Правила Форума редакция от 22.06.2020 |
|
|||||||
|
|
Окажите посильную поддержку, мы очень надеемся на вас. Реквизиты для переводов ниже. |
|
![]() |
|
|
Опции темы | Опции просмотра |
Language
|
|
|
#1
|
|
Неактивный пользователь
Регистрация: 08.04.2008
Сообщений: 10
Репутация: 1
|
Доброго времени суток всем.
У меня проблемка с удалением объекта, а точнее определением был ли он создан. Пробовал разные варианты, но что то не то... Код:
procedure GetView;
var
Param : String;
dq : TOracleQuery;
begin
try try
Param:= 'SELECT view_name, text FROM all_views b WHERE owner = '+#039+LoginUser+#039+
' AND view_name IN (SELECT table_name FROM '+LoginUser+'.entity '+
'WHERE id_table IN ('+TableArrObj.CommaText+'))';
dq:= Do_Query(Param); // Создаю здесь
while not dq.Eof do
begin
....
....
end;
finally
if Assigned(dq) then // Пытаюсь определить был ли создан
dq.Destroy(); // Удаляю
end;
except
on E:EOracleError do
ErrorLog(12,E.ErrorCode,E.Message);
on E:Exception do
ErrorLog(12,12,E.Message);
end;
end;
|
|
|
|
| Реклама: | стол 180х80 прокат | Мебельный магазин: стеклянный шкаф витрина - Переходи на сайт! | балет на льду в казани - redkassa.ru | Рестораны с высокой кухней на Пресне | плыть по волге от ниж новгорода до астрахони |
|
|
#2
|
|
Неактивный пользователь
Регистрация: 07.03.2008
Сообщений: 2
Репутация: 2
|
Попробуй следующим образом
if dq<>nil then dq.free |
|
|
|
| Сказали спасибо: |
|
|
#3
|
|
Неактивный пользователь
Пол:
Регистрация: 28.01.2008
Сообщений: 3
Репутация: 3
|
Переменной dq стоит присвоить nil перед try-блоком. Ведь, если функция Do_Query сгенерирует исключение, то значение dq будет случайным и вызов Destroy приведет в лучшем случае к AV. В блоке finally достаточно вызывать метод Free, который проверят, не является ли указатель на объект нулевым и, если не nil, то вызывает Destroy.
|
|
|
|
| Сказали спасибо: |
|
|
#4
|
|
Неактивный пользователь
Регистрация: 06.12.2007
Сообщений: 6
Репутация: 3
|
блок try ... finally ... end; должен начинаться сразу после Create, в данном случае это Do_Query. А метод Free действительно не требует проверки на nil перед использованием, ибо является "классовым" методом. такие дела
![]() |
|
|
|
| Сказали спасибо: |
|
|
#5
|
|
Неактивный пользователь
Пол:
Регистрация: 19.06.2007
Сообщений: 5
Репутация: 2
|
Хмм... во первых насколько я понимаю, проблема может быть в том - создаст-ли процедура Do_Query объект или нет, иначе смысл проверять был-ли он создан... всвязи с этим, имо, логичнее там-же его проверять (Assigned-ом), при этом в Do_Query явно возвращать nil, если обект не создан. ну и как сказали - ствить try, непосредственно перед его созданием...
Во вторых, метод Free никоим образом не является классовым, и вызывать его не несуществуующем объекте - прямой путь к AV... с уважением... |
|
|
|
| Сказали спасибо: |
|
|
#6
|
|
Неактивный пользователь
Регистрация: 06.12.2007
Сообщений: 6
Репутация: 3
|
Вы заронили сомнение
проверил. нет AV. Насчет "классовости" каюсь, виноват. Я предполагал, что этим объясняется его успешное срабатывание при nil'е. Видимо это достигается отдельными усилиями со стороны компилятора. Тем не менее фраза из хелпа "Unlike Destroy, Free is successful even if the object is nil; so if the object was never initialized, Free won’t result in an error" не мистификация ![]() Добавлено через 1 минуту а Do_Query в данном примере может рассматриваться исключительно как "черный ящик", имхо Последний раз редактировалось BenGun; 29.04.2008 в 11:39.. Причина: Добавлено сообщение |
|
|
|
| Сказали спасибо: |
|
|
#7
|
|
Неактивный пользователь
Пол:
Регистрация: 19.06.2007
Сообщений: 5
Репутация: 2
|
Сам засомневался, но
... var fObject: TObject; i: integer; begin for i := 0 to 10000 do fObject.Free; ... стабильно выдает AV... насчет "черного ящика" - тогда имхо либо надеятся что он вернет nil, если не сможет создать объект, либо само удаление засунуть в try/except, на мой взгляд криво, но другого пути не вижу ![]() да, и вызывать не dq.Destroy, dq.Free... с уважением... |
|
|
|
| Сказали спасибо: |
|
|
#8
|
|
Неактивный пользователь
Пол:
Регистрация: 28.01.2008
Сообщений: 3
Репутация: 3
|
2 BenGun
Мистики никакой нет, все просто: procedure TObject.Free; begin if Self <> nil then Destroy; end; 2 Dark_User Да, я имел в виду ситуацию, когда функция Do_Query сгенерирует исключение, которая сама не обработает, тогда значение переменной - случайное (из стека), поэтому ей нужно присвоить nil в начеле. А использовать Assigned не обязательно - достаточно сравнения на nil. Впрочем Assigned - это то же самое, но используется для свойств-событий, где сравнение с nil не проходит. |
|
|
|
| Сказали спасибо: |
|
|
#9
|
|
Неактивный пользователь
Регистрация: 08.04.2008
Сообщений: 10
Репутация: 1
|
Приветствую все тех кто откликнулся на клич о помощи!
И огромное спасибо всем! Функция Do_Query не не черный ящик. Код:
function Do_Query (SQL_Text: String): TOracleQuery;
var q: TOracleQuery;
begin
try
q:= TOracleQuery.Create(DataModule1);
q.Name:= 'querry_'+IntToStr(ora_cnt);
q.Session:= DataModule1.OracleSession1;
with q do
begin
SQL.Clear;
DeleteVariables;
SQL.Add(SQL_Text);
Execute;
end;
ora_cnt:= ora_cnt + 1;
result:= q;
except
on E:EOracleError do
begin
q.Free();
result:= nil; // как видно возвращаю nil если не создан объект
end;
end;
end;
Возможно я был не очень точен раньше.... Вся проблема идет из за утечки памяти при каждом неудачном выполнении. Код:
dq:= Do_Query(Param); Добавлено через 13 минут Заменил Код:
finally
if Assigned(dq) then
dq.Destroy();
end;
Код:
finally dq.Free; end; Ну прям незнаю что делать ![]() Последний раз редактировалось mambo; 05.05.2008 в 10:40.. Причина: Добавлено сообщение |
|
|
|
|
|
#10
|
|
Неактивный пользователь
Регистрация: 06.12.2007
Сообщений: 6
Репутация: 3
|
я бы сделал примерно так
Код:
type
TStrArray = array of string;
function Get_Query: TOracleQuery;
begin
Result := TOracleQuery.Create(DataModule1);
ora_cnt:= ora_cnt + 1;
Result.Name := 'Querry_' + IntToStr(ora_cnt);
Result.Session := DataModule1.OracleSession1;
end;
function Do_Query(var Q: TOracleQuery; SQL_Text: TStrArray): Boolean;
var
i: Integer;
begin
Result := False;
try
with Q do
begin
SQL.Clear;
DeleteVariables;
for i := Low(SQL_Text) to High(SQL_Text) do
SQL.Add(SQL_Text[i]);
Execute;
end;
Result := True;
except
end;
end;
procedure GetView;
var
Q : TOracleQuery;
begin
Q := GetQuery;
try try
if Do_Query(Q, [
'SELECT view_name, text FROM all_views b WHERE owner = ' + #039 + LoginUser + #039,
'AND view_name IN (SELECT table_name FROM '+LoginUser+'.entity',
'WHERE id_table IN ('+TableArrObj.CommaText+'))'])
then
while not Q.Eof do
begin
....
....
end;
except
on E: EOracleError do
ErrorLog(12, E.ErrorCode, E.Message);
on E: Exception do
ErrorLog(12, 12, E.Message);
end;
finally
Q.Free;
end;
end;
ICQ 111326219. Всегда оффлайн ![]() Последний раз редактировалось BenGun; 08.05.2008 в 16:11.. Причина: Добавлено сообщение |
|
|
|
| Сказали спасибо: |
![]() |
Похожие темы
|
||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| Запись объекта в файл | luivilla | Delphi | 7 | 24.09.2009 17:55 |
| CSS определённого объекта | Scream9 | CSS | 5 | 09.12.2008 03:11 |
| Движение объекта в ActionScript | Skiminok06 | Macromedia Flash | 1 | 14.10.2008 17:04 |
| Error:Предполагается наличие объекта | Wizard2007 | Java Script | 10 | 24.12.2007 01:51 |
|
|