Форум: "Начинающим";
Текущий архив: 2017.04.09;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.002 c