Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.052 c
3-1163412253
SergP
2006-11-13 13:04
2007.02.04
Oracle. Ошибка ORA-06502. Как избавится?


15-1168430363
<rm>
2007-01-10 14:59
2007.02.04
Уместно ли использовать компонент Indy?


2-1168940153
PKM
2007-01-16 12:35
2007.02.04
Работа с TStringGrid.


15-1168682731
Саша-ашаС
2007-01-13 13:05
2007.02.04
Помогите удалить папку


3-1163410504
Gyrus
2006-11-13 12:35
2007.02.04
Скопировать таблицы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский