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

Вниз

Интерфейсы. А надо ли их освобождать?   Найти похожие ветки 

 
DevilDevil ©   (2006-12-04 11:24) [0]

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


 
Сергей М. ©   (2006-12-04 11:26) [1]


> надо ли освобождать интерфейсы


В общем случае - да, надо.
В частном случае - смотря что за случай...


 
DevilDevil ©   (2006-12-04 11:42) [2]

Ну дык зачем освобождать, если он всё равно по завершению приложения освободится?


 
Сергей М. ©   (2006-12-04 11:44) [3]


> если он всё равно по завершению приложения освободится?


Завершение завершению рознь.

Halt - это тоже завершение. Аварийное.
_Release при этом вызван не будет


 
umbra ©   (2006-12-04 11:51) [4]

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


 
DevilDevil ©   (2006-12-04 12:01) [5]

> _Release при этом вызван не будет

Сергей, скажите (просто интересно), а Вы чтобы интерфейс освободить, что делаете?


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


По определению, как бы это сказать... они освобождаются, когда остаются в недоступной памяти. <-- сказал очень плохо, но, надеюсь, поняли

Поэтому, при любом завершении приложения они по идее должны освобождаться. Я не прав?


 
Kolan ©   (2006-12-04 12:03) [6]

Короче, непрарься ничего освобождать ненадо.


 
Сергей М. ©   (2006-12-04 12:06) [7]


> DevilDevil ©   (04.12.06 12:01) [5]


Зависит от самого интерфейса и контекста его использования.
Но предпочитаю явное освобождение - это наглядней, проще для понимания общей логики и немало способствует упрощению отладки приложения.


 
Kolan ©   (2006-12-04 12:10) [8]

> Но предпочитаю явное освобождение - это наглядней, проще
> для понимания общей логики и немало способствует упрощению
> отладки приложения.

Зачем такое надо? Я напротив использую интерфейс когда объект передается в разные методы и непонятно где уничтожать его. Все само удалится...


 
umbra ©   (2006-12-04 12:10) [9]

по определению они освобождаются, когда их счетчик ссылок становится равным нулю. Чтобы он стал равным нулю, каждый клиент должен вызвать метод _Release интерфейса IUnknown. Если по каким-то причинам этот метод не вызван, счетчик не обнулится и интерфейс не освободится. Явным образом вызвать этот метод можно присвоив переменной интефейсного типа nil.


 
DrPass ©   (2006-12-04 12:11) [10]


> В общем случае - да, надо.

В общем случае как раз не надо. Delphi всегда генерирует для интерфейсов вызов _Release при выходе соотв. переменной за пределы области видимости. Надо в том случае, если СОМ-объект требует дополнительных операции для деинициализации. Ну или если логика работы приложения требует. А явное освобождение "просто так" делать не стоит. Это все равно что делать присваивание два раза подряд - чтобы уж наверняка :)


 
Kolan ©   (2006-12-04 12:12) [11]

Автору:
when an object is referenced only through interfaces, there is no need to destroy it manually; the object is automatically destroyed when the last reference to it goes out of scope.


 
Сергей М. ©   (2006-12-04 12:19) [12]


> DrPass ©   (04.12.06 12:11) [10]


Хорошо, поменяем в [1] общий случай и частный случай.
Принципиально это ничего не меняет - все равно нужно уточнять контекст, прежде чем принимать решение.


> Kolan ©   (04.12.06 12:10) [8]


Что "зачем надо" ? Упрощать отладку что ли ?)


 
Anatoly Podgoretsky ©   (2006-12-04 12:23) [13]

> Сергей М.  (04.12.2006 12:06:07)  [7]

Если ты про интерфейсы, используемые в Дельфи, то явное особождение приводит к многочисленным ошибкам.


 
Сергей М. ©   (2006-12-04 12:31) [14]


> Anatoly Podgoretsky ©   (04.12.06 12:23) [13]


Да, приводит. Если нет четкого понимания, где, что, почему, как и при каких условиях происходит в ходе явного освобождения)

У меня не то что "многочисленных" - вообще никаких ошибок не происходит при этом.

Что я не так делаю ?)

Только не надо уже про "делать присваивание два раза подряд - чтобы уж наверняка", мне прекрасно известны действия компилятора при том или ином "варианте освобождения")


 
Anatoly Podgoretsky ©   (2006-12-04 12:32) [15]

> umbra  (04.12.2006 12:10:09)  [9]

Это по каким причинам Дельфи не уменьшит счетчик ссылок при выходе из области видимости. При условии, что шаловливые ручки не применялись?


 
Anatoly Podgoretsky ©   (2006-12-04 12:33) [16]

> DrPass  (04.12.2006 12:11:10)  [10]

И чистить переменную три раза, что совсем очистить.


 
oxffff ©   (2006-12-04 12:47) [17]


> Anatoly Podgoretsky ©   (04.12.06 12:23) [13]
> > Сергей М.  (04.12.2006 12:06:07)  [7]
>
> Если ты про интерфейсы, используемые в Дельфи, то явное
> особождение приводит к многочисленным ошибкам.


многочисленным ошибкам?
Приведите пример пожалуйста.

Ошибки возможны, если вместо

1. a:=nil
2  intFclear(a);
3  a._Release;pointer(a):=nil;

Использовать a._Release,

А явное освобождение надежнее. поскольку можно обернуть в  
      try
      finally
      end;

Да и лучше избегать временных(не объявленных) интерфейсных переменных,
поскольку их в try
                     finally
                     end;

Нормальными средствами не обернешь.


 
Anatoly Podgoretsky ©   (2006-12-04 13:02) [18]

> oxffff  (04.12.2006 12:47:17)  [17]

Вот видишь, сколько ты условий насчитал, а ведь даже малой части не перечислил.


 
oxffff ©   (2006-12-04 13:07) [19]


> Anatoly Podgoretsky ©   (04.12.06 13:02) [18]
> > oxffff  (04.12.2006 12:47:17)  [17]
>
> Вот видишь, сколько ты условий насчитал, а ведь даже малой
> части не перечислил.


Так вы поясните свою точку зрения.


 
DevilDevil ©   (2006-12-04 13:12) [20]


> Anatoly Podgoretsky ©   (04.12.06 12:23) [13]


Анатолий, при всём уважении... Явным особождением в Delphi считается присвоение nil, которое в свою очередь ни к каким ошибкам не приводит


 
Anatoly Podgoretsky ©   (2006-12-04 13:43) [21]

> oxffff  (04.12.2006 13:07:19)  [19]

Я ее озвучил выше


 
Anatoly Podgoretsky ©   (2006-12-04 13:44) [22]

> DevilDevil  (04.12.2006 13:12:20)  [20]

Мало ли, что считается?
Во первых это не явное, а явное _Release и его тоже используют, но часто без необходимости, просто слышали, что это круто.


 
oxffff ©   (2006-12-04 13:50) [23]

Опять все правы. И это хорошо.


 
DevilDevil ©   (2006-12-04 13:56) [24]


> Anatoly Podgoretsky ©   (04.12.06 13:44) [22]


Анатолий, при всём уважении, настаиваю на "использовать _Release в Delphi крайне не рекомендуется". Можно даже сказать "запрещено"


 
Сергей М. ©   (2006-12-04 14:03) [25]


> настаиваю на "использовать _Release в Delphi крайне не рекомендуется".
>  Можно даже сказать "запрещено"


Да глупости же !


 
Anatoly Podgoretsky ©   (2006-12-04 14:54) [26]

> oxffff  (04.12.2006 13:50:23)  [23]

> Опять все правы.

Консенсунс есть продукт непротивления сторон.


 
Джо ©   (2006-12-04 15:13) [27]

Сколько мнений! :) Ну, и я свои 5 копеек. Я "в ручную" освобождаю интерфейсы почти исключительно только тогда, когда этого явно требует логика приложения. Ну, иногда при "глубокой и продолжительной" отладке, именно в отладочных целях.


 
DevilDevil ©   (2006-12-06 09:40) [28]

Зацените, не содержит ли код ошибок:

type PInterface = ^IUnknown;

procedure SAFE_RELEASE(I : PInterface);
begin
  if assigned(I^) then I^ := nil;
end;

SAFE_RELEASE(@MyInteface);


Иногда для каждого интерфеса не хочется писать:
if assigned(MyInteface) then MyInteface := nil;

С SAFE_RELEASE как то проще.

Без указателя (с директивой var) универсальной процедуры (для всех интерфейсов) не получается.


 
Сергей М. ©   (2006-12-06 09:50) [29]


> DevilDevil ©   (06.12.06 09:40) [28]


Не понял..

Зачем эти выкрутасы с косвенными ссылками ?

Зачем вообще нужна эта "универсальная" процедура ?

Приведи пример ее использования ...


 
DrPass ©   (2006-12-06 10:11) [30]


> Зацените, не содержит ли код ошибок:

Во-первых, интерфейс - это и есть указатель,
Во-вторых, достаточно вместо
> if assigned(MyInteface) then MyInteface := nil;


писать MyInteface := nil, и от этого ничего не изменится,
в-третьих, в 99% случаев это вообще можно не писать


 
icWasya ©   (2006-12-06 11:43) [31]

а вот ещё
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=759


 
DevilDevil ©   (2006-12-06 12:26) [32]


> DrPass ©   (06.12.06 10:11) [30]


Хмм. А если написать:
MyInteface := nil;
MyInteface := nil;
MyInteface := nil;

всё будет хорошо во всех версиях Delphi?


> Сергей М. ©   (06.12.06 09:50) [29]
> Зачем вообще нужна эта "универсальная" процедура ?


Смысл тот же, что и в одноимённом Си-шном макросе


 
Сергей М. ©   (2006-12-06 12:31) [33]


> DevilDevil ©   (06.12.06 12:26) [32]


> Смысл тот же, что и в одноимённом Си-шном макросе


А в чем тогда смысл С-шного макроса ?

И в чем смысл слепого его копирования ?


 
DrPass ©   (2006-12-06 13:05) [34]


> всё будет хорошо во всех версиях Delphi?

Ты думаешь, разработчики Delphi настолько бестолковые, что, догадавшись сделать неявное освобождение интерфейсов, при этом не догадались в нем проверять значение указателя? Не беспокойся. Если ты посмотришь на ассемблерный код "compiler-magic" функции IntfClear, ты увидишь - это первое, что она делает.


 
DevilDevil ©   (2006-12-06 13:15) [35]

Ещё вопрос:

допустим я объявил Интерфейс в теле своего класса. Он по-идее не должен быть nil, он может содержать что угодно. Если я его не использую, а в деструкторе класса пишу := nil, не таит ли это скрытой ошибки?


 
Игорь Шевченко ©   (2006-12-06 13:17) [36]


> допустим я объявил Интерфейс в теле своего класса. Он по-
> идее не должен быть nil


После выполнения конструктора он nil


 
Сергей М. ©   (2006-12-06 13:18) [37]


> Он по-идее не должен быть nil


По идее он как раз nil.


 
DevilDevil ©   (2006-12-06 13:23) [38]


> Игорь Шевченко ©   (06.12.06 13:17) [36]


Если объявить не интерфейс, а другую переменную, Integer, например, то её изначальное значение может быть любым. Ты хочешь сказать, что Delphi сам присваивает интерфейсу в конструкторе значение nil. Где можно про это почитать?


 
Anatoly Podgoretsky ©   (2006-12-06 13:27) [39]

> DevilDevil  (06.12.2006 13:15:35)  [35]

Смеешься?
Все члены класса изначально пустые, для интерфейсов это nil
Срочно в справку и читать основы Дельфи.


 
saxon   (2006-12-06 13:28) [40]


> DevilDevil ©   (06.12.06 13:23) [38]
> Где можно про это почитать?

MSDN, Help, Books ...


 
app ©   (2006-12-06 13:29) [41]


> Integer, например, то её изначальное значение может быть
> любым.

Для Integer это ноль.
Это же базис Дельфи.


 
DrPass ©   (2006-12-06 13:44) [42]


> допустим я объявил Интерфейс в теле своего класса. Он по-
> идее не должен быть nil, он может содержать что угодно

Поля класса всегда инициализируются пустыми значениями при создании экземпляра класса, если иное явно не задано в конструкции. Ты путаешь с локальными переменными процедур и функций.
Что касается локальной переменной-указателем на интерфейс, то в отличие от того же integer, компилятор тоже для нее сгенерирует код очистки, так что она по умолчанию будет установлена в nil всегда


 
Игорь Шевченко ©   (2006-12-06 13:58) [43]

DevilDevil ©   (06.12.06 13:23) [38]


> Ты хочешь сказать, что Delphi сам присваивает интерфейсу
> в конструкторе значение nil. Где можно про это почитать?
>


В справке, разумеется.


 
oxffff ©   (2006-12-06 14:28) [44]


>
> DevilDevil ©   (06.12.06 13:23) [38]
>
> > Игорь Шевченко ©   (06.12.06 13:17) [36]
>
>
> Если объявить не интерфейс, а другую переменную, Integer,
>  например, то её изначальное значение может быть любым.
> Ты хочешь сказать, что Delphi сам присваивает интерфейсу
> в конструкторе значение nil. Где можно про это почитать?
>


См. Tobject

-class function InitInstance(Instance: Pointer): TObject;
-procedure CleanupInstance;


 
oxffff ©   (2006-12-06 14:43) [45]

Для локальных переменных interface и string

var  a:IUnknown;
     b:string;

код на asm будет

push 0
push 0

А не sub esp,8

Таким образом они всегда инициализированы.


 
DevilDevil ©   (2006-12-06 15:14) [46]

Всем Thanks!!!



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

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

Наверх




Память: 0.59 MB
Время: 0.258 c
2-1165500423
AlexeyT
2006-12-07 17:07
2006.12.24
Заставить ScrollBox реагировать на перетаскивание ползунка?


2-1164978288
ddddd
2006-12-01 16:04
2006.12.24
оптимизировать запрос


3-1160578319
DelphiLexx
2006-10-11 18:51
2006.12.24
Директива FireBird - USE_EMBEDDED_FB


15-1164902940
vasIzmax
2006-11-30 19:09
2006.12.24
Ради интереса!


15-1165101236
Andy BitOff
2006-12-03 02:13
2006.12.24
Лапша для ушей подсознания.