Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.04;
Скачать: CL | DM;

Вниз

Как узнать, что созданный объект "свободен"?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.035 c
2-1168860633
Tonich
2007-01-15 14:30
2007.02.04
Datetime


1-1165581674
Rule
2006-12-08 15:41
2007.02.04
проблеммы контекстного меню в неглавном меню, при небольшой его


3-1163160336
Kolan
2006-11-10 15:05
2007.02.04
Как колонки сделать строками(SQL)


15-1168804327
altex
2007-01-14 22:52
2007.02.04
Ноут в инет через ПК или Wi-Fi


11-1143445780
nester
2006-03-27 11:49
2007.02.04
[Error] Need imported data reference ($G) to access GUID_NULL