2013-12-08 4 views
2

У меня есть метод, который возвращает IInterface, метод содержит словарь, созданный так:Проблемы с утечками памяти с помощью интерфейса?

Dictionary:= TDictionary<string, IInterface>.Create; 

содержит:

Dictionary.Add('key', TPerson.Create(DatabaseCon)as IInterface); 

Когда я оставил свою текущую программу я получаю утечку памяти сообщений об ошибке на объекте Tperson.

Я пробовал в методе класса деструктора следующее:

private //Global variabels 
    Person:TPerson; 
    I: IInterface; 

begin // in the destructor method of the class 
    Person:= IInterface as TPerson; 
    Person.Free; 
end; 

Но я все еще получаю ошибку ... Как освободить TPerson.Create(DatabaseCon) as IInterface)? Или было бы лучше сохранить TPerson как строку в INI-файле, а затем перетащить имя строки и превратить ее в объект. Но как?

Структура программы:

Inf1= Interface(IInterface) 
//some functions 
Inf2=Interface(Inf1) 
//Some functions 
TPerson= class(TInterfacedPersistent,Inf2) 
// All my functions. 

я могу заставить его работать, если я:

Dictionary.Add ('key', Person) as IInterface); 

Где в методе Create из класса записи:

Person:= TPerson.Create(DatabaseCon); 

и в методе деструктора:

Person.Free; 

, но не так ли это сделать? так как человек класса должен быть сначала создан при доступе к словарю?

ответ

4

Наиболее вероятным объяснением является то, что TPerson не использует ссылку на интерфейс, чтобы управлять временем жизни. Чтобы быть уверенным, нам нужно точно знать, как TPerson реализует IInterface. К сожалению, эта ключевая деталь была исключена из этого вопроса.

Если TPerson происходит от TInterfacedObject, и поэтому срок службы управляется подсчетом ссылок, то ваш код не будет течь. Итак, я уверен, что проблема в том, что реализация вашего класса IInterface не освобождает объект, когда его счетчик ссылок обращается в нуль.

Предполагая, что я правильно, то у вас есть несколько вариантов для решения этой проблемы:

  1. Изменить свой класс для реализации интерфейса ссылочных подсчитываются управлений временем жизни.
  2. Использовать TObjectDictionary<TKey,TValue>, а не TDictionary<TKey,TValue>. Учтите, что тип значения TValue равен TPerson, а не IInterface. И организуйте, чтобы словарь владел своими значениями, чтобы он мог освободить их, когда они были удалены.

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

+0

Вы наследуете от TInterfacedPersistent, поэтому Дэвид прав. Реализация TInterfacedPersistent для AddRef & Release заключается в деле делегировании этого владельцу. Скорее всего, у вас их нет, поэтому у вас нет подсчета ссылок. Вы должны либо наследовать от TInterfacedObject, либо предоставить его владельцу, который выполняет подсчет ссылок или внедряет подсчет ссылок в TPerson самостоятельно. –

+0

После использования TInterfacedObject он просто работает. Многое спасибо Дэвиду и Ливену ;-) – Godfather75

Смежные вопросы