Форум: "Начинающим";
Текущий архив: 2007.02.04;
Скачать: [xml.tar.bz2];
ВнизКак узнать, что созданный объект "свободен"? Найти похожие ветки
← →
AlexanderMS © (2007-01-17 17:55) [0]Иными словами, как узнать, что экземпляр объекта "уже отработал" (вызван Create, затем Free) или вовсе не создавался.
Хотел поставить условиеif Object1 <> nil
, но nil он тогда, когда не был создан (как я понял), и после Free он остаётся не равен nil.
К примеру:var
begin
SL := TSomething.Create;
// SL уже не nil
SL.Free;
// SL всё равно не nil
end;
← →
Rial © (2007-01-17 18:04) [1]Вместо банального Free, используй
Object.Free;
Object:=Nil;
^)procedure rmFree(Var Obj);
asm
//Начало
push ebx
mov ebx, eax
//Вызов метода
mov eax, [ebx]
call System.TObject.Free
//Зануление
xor eax, eax
mov [ebx], eax
//Конец
pop ebx
end;
← →
Desdechado © (2007-01-17 19:01) [2]или FreeAndNil
← →
Sergey Masloff (2007-01-17 23:26) [3]
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free; ============> А если тут что поймаем? Obj мы уже поиксовали ;-))
end;
← →
Джо © (2007-01-17 23:29) [4]> Temp.Free; ============> А если тут что поймаем? Obj мы
> уже поиксовали ;-))
Ничего не поймаем.
← →
Rial © (2007-01-17 23:42) [5]> [3] Sergey Masloff (17.01.07 23:26)
> Temp.Free; ============> А если тут что поймаем? Obj мы
> уже поиксовали ;-))procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
Пустой указатель не страшен.
Так что все кошерно :)
А вообще то, мы же в Temp-е ссылку запомнили,
мы же не Obj.Free делаем.
← →
Sergey Masloff (2007-01-17 23:50) [6]Rial © (17.01.07 23:42) [5]
Почему пустой? Зачем пустой? Не пустой. Нормальный объект. В деструкторе освобождеется ряд ресурсов. При попытке освобождения первого из них получаем исключение (например).
← →
oxffff © (2007-01-17 23:57) [7]Поскольку объект не содержит презаголовок,
то вариант запросить у менеджера памяти информацию о распределение памяти по указателю.
Если память распределна, значит "Что-то есть".
Далее проверить, что в try except "Что это есть".
← →
Sergey Masloff (2007-01-18 00:01) [8]вот например
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TMyObj = class(TComponent)
private
v : Variant;
public
constructor Create(AOwner : TComponent); reintroduce; override;
destructor Destroy; reintroduce; override;
procedure Foo();
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses ComObj;
{ TMyObj }
constructor TMyObj.Create(AOwner: TComponent);
begin
inherited;
v := CreateOleObject("Excel.Application");
end;
destructor TMyObj.Destroy;
begin
Raise Exception.Create("xxx"); // Если это убрать то все честно закрывается
v := Unassigned;
inherited;
end;
procedure TMyObj.Foo;
begin
v.Visible := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
o : TMyObj;
begin
o := TMyObj.Create(self);
o.Foo();
FreeAndNil(o);
// Исключение и Ексель остался висеть
end;
end.
← →
Rial © (2007-01-18 09:45) [9]
>[8] Sergey Masloff (18.01.07 00:01)
> var
> o : TMyObj;
> begin
> o := TMyObj.Create(self);
> o.Foo();
> FreeAndNil(o);
> // Исключение и Ексель остался висеть
Ошибка где - то в другом месте.
Возможно, это замечательное o.Foo() лезет куда - то
далеко, куда ему не положено. Либо кто то другой
портит объект. Вообщем, исключение возникает при
вызове o.Destroy; А от этого уже другие методы лечения.
Попробуй написать просто
o.Destroy;
Теоритически, должно также возникнуть исключение.
Либо, самый простой вариант, исключение вообще
возникает на предыдущей строке.
← →
ors_archangel © (2007-01-18 11:15) [10]
> Rial © (18.01.07 09:45) [9]
Ошибка где-то в другом месте? Вот же "ошибка":
> Raise Exception.Create("xxx"); // Если это убрать то все
> честно закрывается
Имхо, нужно сам деструктор написать, чтобы он старался как можно больше осводить ресурсов перед смертью:
destructor TMyObj.Destroy;
var
errs: array of string;
begin
try
v := Unassigned;
except
on e: Exception do AddErr(e.Message);
end;
inherited;
if errs <> nil then RaiseErrs(errs);
end;
И FreeAndNil в KOL правильнее написан - сначала обнуление, а потом уже работа, которая может вызвать ошибки - Free:
procedure Free_And_Nil( var Obj );
var Obj1: PObj;
begin
Obj1 := PObj( Obj );
Pointer( Obj ) := nil;
Obj1.Free;
end;
← →
Плохиш © (2007-01-18 11:24) [11]
> AlexanderMS © (17.01.07 17:55)
> Иными словами, как узнать, что экземпляр объекта "уже отработал"
> (вызван Create, затем Free) или вовсе не создавался.
Это всё является обязанностью программиста использующего объект. Потому что никакой искусственный интеллект не может протелепатировать какая дикая идея возникла в воспалённом мозгу сумашедшего программиста. Поэтому предусмотренно, что при создании экземпляра объекта, конструктор вернёт ссылку на созданный экземпляр, а программист волен делать с ней всё, что его воспалённой душе угодно. Таким образом, эта Ваша переменная Object1 никакого отношения ни к каким экземплярам объекта не имеет и Вы и, в общем случае, только Вы вольны записывать в неё всё что Вам будет угодно, хоть ссылку на экземпляр объекта, хоть nil, хоть номер дома, на котором сидить пятая ворона в третьем ряду на снимке со спутника штабквартиры нато...
Итак, ответом на Ваш вопрос будет то, что Вы сами должны следить за своим созданием, работой и уничтожением объектов.
> Rial © (18.01.07 09:45) [9]
Спасибо, повеселил :-D
Прочитай код, который Sergey Masloff в деструктор написал ;-)
← →
Rial © (2007-01-18 12:07) [12]> [11] Плохиш © (18.01.07 11:24)
> Спасибо, повеселил :-D
> Прочитай код, который Sergey Masloff в деструктор написал ;-)
Извините если кого обидел где то ...
Завтра экзамен, уже 30 часов не спал. :(
Все, больше пока нигде не пишу, дабы
не скомпрометировать себя.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.02.04;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.053 c