Я сегодня "не в духе".
Поэтому - напишу ЖЁСТКО.
Люди когда же МЫ ВСЕ начнём читать исходники, а не полагать на "эти парни в Embarcadero что-то понаделали".
Вот пример про FMX.
Вот некоторые жалуются, что вот так работает:
А вот так не работает:
Заглянем в исходники FMX.
Там конечно - "трансректально":
Я бы своего коллегу, за подобное - УБИЛ бы на месте.
Хотя у меня есть "пара коллег", которые такой "трансректальный" код пишут, но зато считают в шестнадцатиричной системе в УМЕ и склеивают бинарники неизвестного формата. Они - ГЕНИИ. Но их - ЕДИНИЦЫ.
На них - "не надо равняться".
Видим, что Reference - в "ветке else" - нигде не инициализируется. Что уже вызывает ВОЗГЛАС - "дебилы".
Как я это понял? Банально - "Ctrl-F".
Ну и ещё вот эта строчка:
Это же - 3.14-ц... Простите за грубость...
А если Reference - это локальная переменная? Которая на СТЕКЕ!
Простите - это - 3.14-ц...
Я бы на месте Embarcadero положил бы туда Proxy, который бы делал форму при ПЕРВОМ же обращении.
Или хотя бы "кидало вменяемое исключение".
Как? Это - "тема отдельного поста".
В общем - "ребятам из Embarcadero" - двойка. С ДВУМЯ жирными минусами.
Или я - чего-то не понимаю.
Но я не об этом.
Но!
Люди "почему-то" начинают лезть "в кишки" вместо того, чтобы сделать вот что:
О чём я?
НАДО "читать исходники" и "писать Assert'ы". (Коротко. Ещё немного "рассуждений о RAII")
Это в ПЕРВУЮ очередь.
А во ВТОРУЮ очередь - ИЗБАВИТЬСЯ от ХОККЕЯ - О термине "хоккей" и Портирование на Delphi XE4 идёт вполне успешно
И Embarcadero - ТОЖЕ.
Простите за ГРУБОСТЬ.
P.S. А "простым программерам" скажу - "ну забудьте уже про эту глупость - CreateForm" - пользуйтесь конструкторами.
Опять же. Простите за ГРУБОСТЬ.
P.P.S. Пишите Assert'ы.
Поэтому - напишу ЖЁСТКО.
Люди когда же МЫ ВСЕ начнём читать исходники, а не полагать на "эти парни в Embarcadero что-то понаделали".
Вот пример про FMX.
Вот некоторые жалуются, что вот так работает:
procedure SomeLocalProcedure; var l_Form : TSomeForm; begin l_Form := TSomeForm.Create(nil); l_Form.SomeProperty := SomeData; end;
А вот так не работает:
procedure SomeLocalProcedure; var l_Form : TSomeForm; begin Application.CreateForm(TSomeForm, l_Form); l_Form.SomeProperty := SomeData; // - тут получаем AV end;
Заглянем в исходники FMX.
Там конечно - "трансректально":
procedure TApplication.CreateForm(const InstanceClass: TComponentClass; var Reference); var Instance: TComponent; RegistryItems : TFormRegistryItems; RegItem : TFormRegistryItem; begin if FRealCreateFormsCalled then begin Instance := TComponent(InstanceClass.NewInstance); TComponent(Reference) := Instance; try Instance.Create(Self); for RegItem in FCreateForms do if RegItem.InstanceClass = InstanceClass then begin RegItem.Instance := Instance; RegItem.Reference := @Reference; end; except TComponent(Reference) := nil; raise; end; end else begin SetLength(FCreateForms, Length(FCreateForms) + 1); FCreateForms[High(FCreateForms)] := TFormRegistryItem.Create; FCreateForms[High(FCreateForms)].InstanceClass := InstanceClass; FCreateForms[High(FCreateForms)].Reference := @Reference; // Add the form to form registry in case RegisterFormFamily will not be called if FFormRegistry.ContainsKey(EmptyStr) then begin RegistryItems := FFormRegistry[EmptyStr]; end else begin RegistryItems := TFormRegistryItems.Create; FFormRegistry.Add(EmptyStr, RegistryItems); end; RegistryItems.Add(FCreateForms[High(FCreateForms)]); end; end;
Я бы своего коллегу, за подобное - УБИЛ бы на месте.
Хотя у меня есть "пара коллег", которые такой "трансректальный" код пишут, но зато считают в шестнадцатиричной системе в УМЕ и склеивают бинарники неизвестного формата. Они - ГЕНИИ. Но их - ЕДИНИЦЫ.
На них - "не надо равняться".
Видим, что Reference - в "ветке else" - нигде не инициализируется. Что уже вызывает ВОЗГЛАС - "дебилы".
Как я это понял? Банально - "Ctrl-F".
Ну и ещё вот эта строчка:
FCreateForms[High(FCreateForms)].Reference := @Reference;
Это же - 3.14-ц... Простите за грубость...
А если Reference - это локальная переменная? Которая на СТЕКЕ!
Простите - это - 3.14-ц...
Я бы на месте Embarcadero положил бы туда Proxy, который бы делал форму при ПЕРВОМ же обращении.
Или хотя бы "кидало вменяемое исключение".
Как? Это - "тема отдельного поста".
В общем - "ребятам из Embarcadero" - двойка. С ДВУМЯ жирными минусами.
Или я - чего-то не понимаю.
Но я не об этом.
Но!
Люди "почему-то" начинают лезть "в кишки" вместо того, чтобы сделать вот что:
procedure SomeLocalProcedure; var l_Form : TSomeForm; begin l_Form := nil; // - ДА ДА - НЕ ЗАБЫВАЙТЕ, что там VAR Application.CreateForm(TSomeForm, l_Form); Assert(l_Form <> nil); Assert(l_Form Is TSomeForm); Assert(l_Form.InheritsFrom(TSomeForm)); l_Form.SomeProperty := SomeData; // - тут получаем AV end;
О чём я?
НАДО "читать исходники" и "писать Assert'ы". (Коротко. Ещё немного "рассуждений о RAII")
Это в ПЕРВУЮ очередь.
А во ВТОРУЮ очередь - ИЗБАВИТЬСЯ от ХОККЕЯ - О термине "хоккей" и Портирование на Delphi XE4 идёт вполне успешно
И Embarcadero - ТОЖЕ.
Простите за ГРУБОСТЬ.
P.S. А "простым программерам" скажу - "ну забудьте уже про эту глупость - CreateForm" - пользуйтесь конструкторами.
Опять же. Простите за ГРУБОСТЬ.
P.P.S. Пишите Assert'ы.
Напишите в CodeCentral. Можно без слова ДЕБИЛЫ. Они и сами догадаются :) Хотя можно и с этим словом, все равно не оценят...
ОтветитьУдалитьИначе НИКОГДА не будет исправлено. Не пишут об ошибке, значите ее вроде бы и нет.
Я про "Reference - в "ветке else" - нигде не инициализируется"
ОтветитьУдалитьНу так и напишите :-) Я - "все козыри дал".
УдалитьСамому - "лень". Ибо уже писал и не раз. Толку то?