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

Вниз

Delphi XE: изменили FreeAndNil?   Найти похожие ветки 

 
Masterucs ©   (2015-08-11 12:29) [0]

Вот такой код в Delphi XE в SysUtils:

procedure FreeAndNil(var Obj);
var
 Temp: TObject;
begin
 Temp := TObject(Obj);
 Pointer(Obj) := nil;
 Temp.Free;
end;


Почему он принимает var Obj? Должен по идее TObject.
Нарушается безопасность, ведь все равно он пытается любую ссылку к TObject привести.


 
Германн ©   (2015-08-11 12:37) [1]


> Delphi XE: изменили FreeAndNil?

Этот код испокон веков один и тот же. При чем тут ХЕ?


 
Kerk ©   (2015-08-11 12:40) [2]


> Почему он принимает var Obj? Должен по идее TObject.

Попробуй написать аналог с TObject
Узнаешь почему :)


 
Masterucs ©   (2015-08-11 13:02) [3]


> Попробуй написать аналог с TObject

var параметр должен быть identical...


 
brother ©   (2015-08-11 13:31) [4]

> Должен по идее TObject.

ээээ, с чего бы? только потому, что все остальные потомки?


 
Kerk ©   (2015-08-11 13:46) [5]


> var параметр должен быть identical...

Ну вот и ответ почему оно сделано так, как сделано :)


 
NoUser ©   (2015-08-11 23:40) [6]

FreeAndNil, конечно, крутая штука, но мне она как-то сразу не понравилась...


TFreeOrReleaseProc = procedure of object;          

procedure FrezMem(var Ptr); inline;
procedure FrezObj(var Obj); overload; inline;
procedure FrezObj(var Obj; FreeOrReleaseProc :TFreeOrReleaseProc); overload; inline;

//-------------------------------------------------------------------------------

procedure FrezMem(var Ptr);
begin
FreeMem(AtomicExchange(Pointer(Ptr), nil));
end;

procedure FrezObj(var Obj);
begin
TObject(AtomicExchange(Pointer(Obj), nil)).Free;
end;

procedure FrezObj(var Obj; FreeOrReleaseProc :TFreeOrReleaseProc);
begin
if ( AtomicExchange(Pointer(Obj), nil) <> nil ) then FreeOrReleaseProc;
end;

//-------------------------------------------------------------------------------

FrezObj(Form,  Form.Release);
// or
FrezObj(IoCpSocket,  IoCpSocket.Release);



 
Игорь Шевченко ©   (2015-08-12 13:18) [7]

NoUser ©   (11.08.15 23:40) [6]

А зачем этот велосипед, тем более, с такими кондовыми именами ?


 
NoUser ©   (2015-08-12 13:28) [8]

Непременно Вам расскажу, если узнаю Вашу версию необходимости FreeAndNil.


 
K-1000 ©   (2015-08-12 19:35) [9]


> NoUser ©   (12.08.15 13:28) [8]
>
> Непременно Вам расскажу, если узнаю Вашу версию необходимости
> FreeAndNil.


Вопрос не ко мне, но отвечу:
http://www.gunsmoker.ru/2009/04/freeandnil-free.html


 
NoUser ©   (2015-08-12 20:30) [10]

Внимание! Пост направлен на обоснование моей точки зрения :D Просьба все негативные проклятия изливать где-то ещё ;) ))))

Да простит меня многоуважаемый GunSmoker за такой вот ответ Игорю Шевченко © :

Это ремни безопасности, которые нужно и уже можно использовать всегда, и чтобы меньше печатать.
)))


 
Игорь Шевченко ©   (2015-08-12 21:39) [11]

NoUser ©   (12.08.15 13:28) [8]

Моя версия полностью совпадает с изложенной тут:
http://www.nickhodges.com/post/Using-FreeAndNil.aspx


 
NoUser ©   (2015-08-12 22:32) [12]

Игорь Шевченко ©   (12.08.15 21:39) [11]

Спасибо, принимается, прочитал и вспомнил свои похожие мысли/сомнения, в момент первого знакомства с данным функционалом.

Мой велосипед хочет показать любителям фриониливания, что есть еще и динамически выделяемая память (а не только объекты), и потоки, и "фрифобные" объекты.

Но если копнуть дальше:
procedure TObject.Free;
begin
// under ARC, this method isn"t actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
 if Self <> nil then
   Destroy;
{$ENDIF}
end;

то возникает следующий вопрос:

А многие ли из мастеров вызывают именно Destroy вместо Free ?


 
Игорь Шевченко ©   (2015-08-12 23:11) [13]

NoUser ©   (12.08.15 22:32) [12]


> А многие ли из мастеров вызывают именно Destroy вместо Free
> ?


Многие из мастеров читают справку, в которой написано:

"Do not call Destroy directly. Call Free instead. Free verifies that the object reference is not nil before calling Destroy. "

Впрочем, давайте дальше про ARC смотреть:

function TObject.__ObjRelease: Integer;
begin
 Result := AtomicDecrement(FRefCount) and not objDisposedFlag;
 if Result = 0 then
 begin
   __MarkDestroying(Self);
   if __SetDisposed(Self) then
     Destroy
   else
     FreeInstance;
 end;
end;


В результате вызовется тот же Destroy при необходимости.


 
NoUser ©   (2015-08-12 23:17) [14]


> Free verifies that the object reference is not nil before
> calling Destroy

А спрашивает ли себя мастер, читающий справку, зачем же предпроверка на нил?


 
Игорь Шевченко ©   (2015-08-13 10:54) [15]

NoUser ©   (12.08.15 23:17) [14]

Ты если чего хочешь сказать, говори прямо, а то в твоих намеках можно еще две страницы смысл искать. Проверка на nil в данном случае (по мнению мастера, читающего справку) нужна, чтобы избежать исключения Access Violation.


 
NoUser ©   (2015-08-13 15:38) [16]

Почему намёках, - конкретные вопросы то.


> Проверка на nil в данном случае (по мнению мастера, читающего
> справку) нужна, чтобы избежать исключения Access Violation.


Прямо спрашиваю:
В каких таких ситуациях мастер позволяет себе отправить на освобождение то чего нет?


 
Игорь Шевченко ©   (2015-08-13 17:44) [17]

NoUser ©   (13.08.15 15:38) [16]

Таких ситуаций не существует...


 
NoUser ©   (2015-08-13 21:11) [18]

Игорь Шевченко ©   (13.08.15 17:44) [17]

То есть, если в том коде, который написан мастером, все вызовы Obj.Free заменить на Obj.Destroy то можно не опасаться за стабильность работы программы?

К чему это я - да к тому, что если кто-то находит/приводит серьезные аргументы не в пользу FreeAndNil, а при этом сам напрямую не вызывает Destroy - значит он лукавит.


 
jack128_   (2015-08-14 08:38) [19]

По хорошему FreeAndNil нужно так переписать

procedure FreeAndNil<T: class>(var Obj: T);
var
 Temp: TObject;
begin
 Temp := Obj;
 Obj := nil;
 Temp.Free;
end;


к сожалению дельфи не поддерживает дженерик функции + не работает вывод дженерик параметров для var аргументов.


 
Cobalt ©   (2015-08-14 16:20) [20]

> NoUser ©   (13.08.15 15:38) [16]
>
> Прямо спрашиваю:
> В каких таких ситуациях мастер позволяет себе отправить
> на освобождение то чего нет?

в деструкторе класса, если в конструкторе возникла исключительная ситуация.


 
NoUser ©   (2015-08-14 16:33) [21]

> Cobalt ©   (14.08.15 16:20) [20]

Проиллюстрируйте, пожалуйста, примерчиком.


 
Cobalt ©   (2015-08-14 16:40) [22]

constructor TBasicAction.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FClients := TList.Create;
end;

destructor TBasicAction.Destroy;
begin
 inherited Destroy;
 if Assigned(ActionComponent) then
   ActionComponent.RemoveFreeNotification(Self);
 while FClients.Count > 0 do
   UnRegisterChanges(TBasicActionLink(FClients.Last));
 FreeAndNil(FClients);
end;



Страницы: 1 вся ветка

Текущий архив: 2017.04.09;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.007 c
2-1439285376
Masterucs
2015-08-11 12:29
2017.04.09
Delphi XE: изменили FreeAndNil?


2-1439375893
GAZot
2015-08-12 13:38
2017.04.09
Пакетная передача данных по протоколу UDP


15-1458584450
Kilkennycat
2016-03-21 21:20
2017.04.09
Прощай, авиамоделизм.


15-1460136529
aka
2016-04-08 20:28
2017.04.09
Лицензионное ПО


2-1439406925
oleg_teacher
2015-08-12 22:15
2017.04.09
Вопрос взаимодействия Delphi и Excel