Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
15-1458584450
Kilkennycat
2016-03-21 21:20
2017.04.09
Прощай, авиамоделизм.


15-1460484629
Dmk
2016-04-12 21:10
2017.04.09
Регистрация Delphi


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


15-1459970604
K-1000
2016-04-06 22:23
2017.04.09
Кто играет в шахматы?


4-1282656910
Unknown_user
2010-08-24 17:35
2017.04.09
Запрет получения фокуса приложения





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский