Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Возможность создания новых типов интерфейсов в новых версиях Delphi / 25 сообщений из 53, страница 1 из 3
25.03.2018, 16:10
    #39620153
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Для тех, кто регулярно штудирует дельфийские What's New и параллельно читает блоги Марко Канту - это далеко и не новость. Но ИМНО лишний раз поделиться все же стоит.
Речь идет о применении двух относительно новых атрибутах из System.pas А именно WeakAttribute, UnsafeAttribute .
Изначально оба этих атрибута введены для поддержки ARC ( Automatic Reference Counting ) в мобильных поделках на Дельфях.
Без них не получается обойти проблему взаимного увеличения RefCount между ссылающихся друг на друга объектов и как следствие невозможность правильно освободить память основываясь лишь на механизме ARC.

Спрашивается, чем эти атрибуты могут быть полезны для пишущих под Десктоп? А вот чем:
Они позволяют реализовать нечто на подобии т.н. "чистых интерфейсов". Т.е. интерфейсов не обремененных заботой об увеличении/уменьшении числа ссылок и "самообнуляющихся" интерфейсов.
Нет, безусловно создавать минимальную реализацию IInterface, ну или наследоваться от TInterfacedObject или от TSingletonImplementation по любому придется.
Но все же есть интересные нюансы в плане работы с такими интерфейсами.

Возьмем пример более простого UnsafeAttribute
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
type
  ISomeInterface = interface
    ['{1EB95902-AFF7-4230-9B26-D6CDBFD69DF9}']
    procedure DoSomething;
  end;

  TSomeClass = class(TInterfacedObject, ISomeInterface)  // Наследуемся от TInterfacedObject, чтобы убедиться что механизм RefCount работать не будет
    procedure DoSomething;
  end;

procedure TestProc;
var
  SC: TSomeClass;
  [Unsafe] ISI: ISomeInterface; // !!! Unsafe
begin
  SC := TSomeClass.Create;
  ISI := SC; // именно таким синтаксисом а не ISI := SC as ISomeInterface;
  ISI.DoSomething;
  ISI := nil; // _Release вызван не будет (уничтожение объекта SC: TSomeClass не произойдет)
  SC.Free;
end;


В данном случае можем рассматривать ISI: ISomeInterface как просто своеобразный облегченный Pointer на интерфейс с поддержкой от компилятора.

!!! Но, если вместо
Код: plaintext
ISI := SC
вы напишете
Код: plaintext
ISI := SC as ISomeInterface
то _AddRef все же будет вызван, что в случае с TInterfacedObject приведет к увеличению RefCount и тогда на SC.Free вы получите эксепшен из процедурки TInterfacedObject.BeforeDestruction, которая при уничтожении проверяет RefCount на равенство 0.

ИМХО: Как по мне так это очередной баг компилятора. Если уж для Unsafe интерфейсов не вызывается _Release, то и _AddRef тоже не должен вызываться ни при каком синтаксисе.
Но либо можно пользоваться простым присвоением (как в примере). Либо же объекты должны наследоваться от TSingletonImplementation, где и без того учет количества ссылок не важен, но тогда и тогда и этот unsafe не особо-то уже и нужен

Теперь о применении WeakAttribute
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
type
  ISomeInterface = interface
    ['{1EB95902-AFF7-4230-9B26-D6CDBFD69DF9}']
    procedure DoSomething;
  end;

  TSomeClass = class(TSingletonImplementation, ISomeInterface)  // В данном случае наследуемся от TSingletonImplementation
    procedure DoSomething;
  end;

procedure TestProc;
var
  SC: TSomeClass;
  [Weak] ISI: ISomeInterface;
begin
  SC := TSomeClass.Create;
  ISI := SC; // !!! можно и ISI := SC as ISomeInterface но только для TSingletonImplementation
  SC.Free;
  ISI.DoSomething; // Здесь самое интересное. К этому моменту ISI будет автоматически обнулен ( = nil ), поэтому схлопочем AccessViolation
end;


!!! WeakAttribute лучше НЕ использовать с объектами, где учитывается RefCount типа TInterfacedObject
Причина в том, что при использовании синтаксиса ISI := SC произойдет "непредвиденный" запуск _Release ( ИМНО Побочный баг ведения списка weak ссылок ) и ваш TInterfacedObject может быть преждевременно уничтожен.
В случае же с TSingletonImplementation и подобных это не важно.

Главный же плюс от применения Weak интерфейсов в том, что они автоматически обнуляются ( переменным присваивается nil ) при уничтожении объекта на который они ссылаются (см. пример).
Т.е. фактически Дельфина теперь ведет managed учет weak ссылок. И это может быть полезно в некоторых схемах, поскольку мы можем узнать об уничтожении главного объекта проверив интерфейсную переменную на nil.

!!! Нужно быть внимательным при объявлении [Unsafe] и [Weak] атрибутов.
Потому как, очень просто случайно написать например Week вместо Weak. Дельфи проглотит это без ошибок и лишь с малозаметным предупреждением типа "W1025 Unsupported language feature: 'custom attribute'", поскольку для него это просто имя некого неимплементированного атрибута. И тогда вместо Weak-интерфейса вы получите обычный и можете об этом и не узнать.
...
Рейтинг: 0 / 0
25.03.2018, 16:37
    #39620157
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
1. В топку интерфейсы.
2. В топку ARC.
...
Рейтинг: 0 / 0
25.03.2018, 17:01
    #39620162
под ван
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreat1. В топку интерфейсы.
2. В топку ARC.
человек столько писал и офармлял а ты взял и сказал как отрезал . Нельзя же так с человеками - уважай их труд а то они писать перестанут.
...
Рейтинг: 0 / 0
25.03.2018, 19:09
    #39620186
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreat1. В топку интерфейсы.
2. В топку ARC.А в след за ними в топку и старых заскорузлых отшельников-староверов aka rgreat.
Бо оне дюже мешаютЪ юным отрокам постигать что-то новое и диковинно-заморское.
Поелику интерфейсы они суть благо великое, ежели их православно уготовати, аки они суть в диковинных поделках на C#.

( так даже деду rgreat-у будет понятнее ) ;)
...
Рейтинг: 0 / 0
25.03.2018, 19:49
    #39620193
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Leonid,

Я помоложе многих тут буду. А интерфейсы в дельфях с незапамятных времен есть.
Что не мешает им быть весьма спорным инструментом вне узкого круга задач.

Так что с ретроградностью ты мимо.
...
Рейтинг: 0 / 0
25.03.2018, 19:54
    #39620194
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreat1. В топку интерфейсы.
2. В топку ARC.
всячески поддержу
...
Рейтинг: 0 / 0
25.03.2018, 21:24
    #39620214
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatЯ помоложе многих тут буду. А интерфейсы в дельфях с незапамятных времен есть.
Что не мешает им быть весьма спорным инструментом вне узкого круга задач.
Так что с ретроградностью ты мимо.Возраст он часто в голове. Нередко можно встретить и по-старчески кряхтящих подростков. Особенно часто такие встречаются среди "ботаников".

Интерфейсы же сами по себе это очень полезный инструмент. А-то что он в Дельфях изначально был создан для поддержки COM и поэтому и изначально отягощен явным заданием GUID и поддержкой RefCount - это издержки данной старинной реализации.
Поэтому-то уже давно все и выкручивались с помощью заглушек на _AddRef и _Release как в TSingletonImplementation.
Хотя, возможно нужно было бы просто давно ввести новый тип. Что-нибудь типа "simpleinterface" и все было бы идеологически куда проще.
Пока же имеем, что имеем. Зато вот появляются такие вещи как экзотические для найтива "самообнуляемые интерфейсы".

В любом случае: не хочешь - не пользуйся.
Только когда сама библиотека давно использует интерфейсы вдоль и поперек, говорить что-то типа "в топку интерфейсы" - это как бессмысленно в лужу пер... ;)
( кстати defecator в этом всегда мастер ;) )
...
Рейтинг: 0 / 0
25.03.2018, 22:13
    #39620219
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Опиши задачи где интерфейсы есть больше смысла применять чем другие инструменты.

И почему.
...
Рейтинг: 0 / 0
25.03.2018, 22:20
    #39620221
asviridenkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatОпиши задачи где интерфейсы есть больше смысла применять чем другие инструменты.

И почему.

Например
Код: pascal
1.
for элемент in функция_возвращающая_список do 
...
Рейтинг: 0 / 0
25.03.2018, 22:23
    #39620223
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
asviridenkovrgreatОпиши задачи где интерфейсы есть больше смысла применять чем другие инструменты.

И почему.

Например
Код: pascal
1.
for элемент in функция_возвращающая_список do 

Дык, уже куча классов имеет энумераторы. Интерфейсы зачем?
...
Рейтинг: 0 / 0
25.03.2018, 22:27
    #39620224
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Если это нужно именно как самоочищающийся результат функции у себя для этого использую TArrayEx<T>.

У него и энумератор есть и самоубъется он сам при выходе из процедуры.
...
Рейтинг: 0 / 0
25.03.2018, 23:07
    #39620236
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatОпиши задачи где интерфейсы есть больше смысла применять чем другие инструменты.
И почему.rgreat, почему я тебе должен хрестоматийные истины расписывать. Или тебе самому лениво посмотреть?
В паре/тройке предложений: interface - это явное отделение собственно "интерфеса" класса от его непосредственной реализации при котором не нужно опираться на единую ветвь наследования. Особенно когда наследование по одной ветви может являться нарушением инкапсуляции либо вообще не возможно или бессмысленно в рамках некоторой архитектуры.

На практике действительно часто либо не имеет смысла и даже вредно, либо принципиально нет возможности создавать иерархию в рамках наследования из одной цепи, но нужен "интерфейс" ( в данном случае можешь понимать "интерфейс" как нечто объединяющее твои возможно весьма разнородные объекты ), который позволит, например, однообразно передавать их в какую-то обобщенную обработку, которая в данном случае не нуждается в знании о всех этих конкретных классах.
Так понятнее? Если нет - читай книжечки про паттерны и прочее.
...
Рейтинг: 0 / 0
25.03.2018, 23:31
    #39620240
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatasviridenkovпропущено...


Например
Код: pascal
1.
for элемент in функция_возвращающая_список do 

Дык, уже куча классов имеет энумераторы. Интерфейсы зачем?

Есть некий метод который внутри что-то умеет делать с классом реализующим интерфейс энумератор... Какой класс передан неважно, важно что он реализует интерфейс...

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TSome.Test(aValue: IEnumerator)
// К примеру List и Queue, а также семантический не родственный DataSet реализуют интерфейс IEnumerator
var
  Some: TSome;
Some.Test(List);
Some.Test(Queue);
Some.Test(DataSet);
Some.Test(Form); // К примеру внутри идет проверка на реализацию IEnumerator. Если интерфейс не реализован, то поведение другое.
...
Рейтинг: 0 / 0
25.03.2018, 23:47
    #39620242
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Leonidrgreat, почему я тебе должен хрестоматийные истины расписывать. Или тебе самому лениво посмотреть?
Вдруг ты мне "глаза откроешь"?

На практике действительно часто либо не имеет смысла и даже вредно, либо принципиально нет возможности создавать иерархию в рамках наследования из одной цепи, но нужен "интерфейс" ( в данном случае можешь понимать "интерфейс" как нечто объединяющее твои возможно весьма разнородные объекты ), который позволит, например, однообразно передавать их в какую-то обобщенную обработку, которая в данном случае не нуждается в знании о всех этих конкретных классах.
Так понятнее? Если нет - читай книжечки про паттерны и прочее.Дык о чем и речь. Область применения интерфейсов в реальной жизни весьма ограничена.
...
Рейтинг: 0 / 0
25.03.2018, 23:50
    #39620244
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
X-CiteЕсть некий метод который внутри что-то умеет делать с классом реализующим интерфейс энумератор... Какой класс передан неважно, важно что он реализует интерфейс...

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TSome.Test(aValue: IEnumerator)
// К примеру List и Queue, а также семантический не родственный DataSet реализуют интерфейс IEnumerator
var
  Some: TSome;
Some.Test(List);
Some.Test(Queue);
Some.Test(DataSet);
Some.Test(Form); // К примеру внутри идет проверка на реализацию IEnumerator. Если интерфейс не реализован, то поведение другое.

И зачем ради этого такие сложности городить?

Чаще всего в жизни эти самые "List,Queue,DataSet,Form" будут рождены от общего родителя.
Ибо если нет, то и скорей всего этот самый Some.Test - скорей вскего будет некой синтетической, и никому реально не нужной процедурой.
...
Рейтинг: 0 / 0
25.03.2018, 23:53
    #39620245
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Ну или так проще сделать интерфейсов:

Код: pascal
1.
2.
3.
4.
Some.Test(List.Test);
Some.Test(Queue.Test);
Some.Test(DataSet.Test);
Some.Test(Form.Test);



Где - Test - это некий общий тип.
...
Рейтинг: 0 / 0
25.03.2018, 23:59
    #39620247
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
*без интерфейсов
...
Рейтинг: 0 / 0
26.03.2018, 00:25
    #39620252
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatВдруг ты мне "глаза откроешь"?
Дык о чем и речь. Область применения интерфейсов в реальной жизни весьма ограничена.
"Глупый ты, Лешка, – улыбнулся полковник. – Прямо беда с тобой. Ты бы хоть книжку какую-нибудь прочитал.
- А зачем, Иван Антонович?
- Хотя, правильно. Тебе может и не к чему."
(с) "О бедном гусаре замолвите слово".

Я могу, например, предположить, что либо сложность проектов, с которыми ты пока сталкивался не велика, либо у тебя могут быть серьезные костыли с проектированием больших проектов, либо это твои собственный подход.
Но опять же, лично ты можешь не пользоваться какой-либо возможностью или "механизмом" и вполне себе жить и без этого.
Либо по неумению/незнанию, либо по принципиальному нежеланию. В любом случае - тогда это лично твои тараканы и обсуждать их мы не будем.
Примеры же повсеместного использования интерфейсов ты можешь найти как в самой дельфийской библиотеке, так и во множестве сторонних проектов.
Более того, есть вполне серьезные и резонные измышления о большой полезности "интерфейсного" подхода в проектировании.
Но возможность и полезность - это не значит необходимость. Поэтому лично тебя никто не заставляет.
...
Рейтинг: 0 / 0
26.03.2018, 00:33
    #39620253
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
Leonid "Глупый ты, Лешка, – улыбнулся полковник. – Прямо беда с тобой. Ты бы хоть книжку какую-нибудь прочитал.
- А зачем, Иван Антонович?
- Хотя, правильно. Тебе может и не к чему."
(с) "О бедном гусаре замолвите слово".
YouTube Video
...
Рейтинг: 0 / 0
26.03.2018, 00:35
    #39620255
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatЧаще всего в жизни эти самые "List,Queue,DataSet,Form" будут рождены от общего родителя.От какого общего родителя они будут рождены? Ну разве что от TObject-а
У тебя что все объекты в твоих собственных иерархиях в рамках только одной ветви наследуются? Если так - то это "тихий ужас".
...
Рейтинг: 0 / 0
26.03.2018, 00:41
    #39620256
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
LeonidУ тебя что все объекты в твоих собственных иерархиях в рамках только одной ветви наследуются? Если так - то это "тихий ужас".Там пошутил, сам посмеялся.
Молодец.
...
Рейтинг: 0 / 0
26.03.2018, 00:48
    #39620258
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatОк, я понял.
У тебя талант говорить глупости с умным видом.
По сути ничего не сказано.Тебе по сути я уже сказал. Тебе даже простенький пример привели. И как раз твои возражения по этому примеру и вызывают вопросики... ;)

Ну еще как пример могу тебе привести, что чисто с прикладной точки зрения ( без каких-то рассуждалок о проектировании ) ты, например, можешь использовать единый интерфейс для сохранения в XML/JSON или еще куда своих разнородных ( не наследуемых от одного предка ) объектов. При этом процедурка не обязана вообще ничего знать о твоих объектах, а только об одном их общем интерфейсике.
Еще раз тебе говорю - это будет удобная возможность, а не обязанность.
Так же как ты, например, можешь и не пользоваться удобством обобщенных списков, а писать все на TList-ах и заниматься приведением. Ты просто не будешь пользоваться более удобным в данном случае "механизмом". Вот и все.
...
Рейтинг: 0 / 0
26.03.2018, 00:51
    #39620259
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
rgreatLeonidУ тебя что все объекты в твоих собственных иерархиях в рамках только одной ветви наследуются? Если так - то это "тихий ужас".Там пошутил, сам посмеялся.
Молодец.Ну а как еще тебя понять?
Если ты очевидные удобства не принимаешь в принципе. Даже когда тебе детально "расжевывают", где это хорошо работает.
...
Рейтинг: 0 / 0
26.03.2018, 00:58
    #39620261
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
LeonidТебе по сути я уже сказал. Тебе даже простенький пример привели. И как раз твои возражения по этому примеру и вызывают вопросики... ;)Меньше софистики, больше конкретики.
Ну еще как пример могу тебе привести, что чисто с прикладной точки зрения ( без каких-то рассуждалок о проектировании ) ты, например, можешь использовать единый интерфейс для сохранения в XML/JSON или еще куда своих разнородных ( не наследуемых от одного предка ) объектов. При этом процедурка не обязана вообще ничего знать о твоих объектах, а только об одном их общем интерфейсике.Подставь вместо "интерфейсика" общий "классик" для экспорта данных в XML/JSON и ничего по сути не изменится.
Еще раз тебе говорю - это будет удобная возможность, а не обязанность.И слава богу.
Так же как ты, например, можешь и не пользоваться удобством обобщенных списков, а писать все на TList-ах и заниматься приведением. Ты просто не будешь пользоваться более удобным в данном случае "механизмом". Вот и все.
Удобство интерфейсов часто в лучшем случае субъективно.
А в реальности концов потом в чужом коде концов не найти.
...
Рейтинг: 0 / 0
26.03.2018, 01:00
    #39620262
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Возможность создания новых типов интерфейсов в новых версиях Delphi
LeonidНу а как еще тебя понять?Как написано. Русским по белому.

Если ты очевидные удобства не принимаешь в принципе. Даже когда тебе детально "расжевывают", где это хорошо работает.Не увидел "разжевалки".

А "очевидные удобства" таковы в теории а не на практике. А я практик.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Возможность создания новых типов интерфейсов в новых версиях Delphi / 25 сообщений из 53, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]