Delphi TDictionary: значения заменяются автоматически при наличии одинакового ключа

Я использую Delphi XE5. Это резюме моего кода, следующий код работает, но в моем коде должно быть что-то, что разрушает нормальное поведение:

unit Class1;
type
 TClass1 = class
  private 
    FDic:TDictionary<String,String>.Create;
  public
constructor create;
    procedure insertValue(key,value:String);
  end;

 implementation
 constructor TClass1.create;
 begin
   FDic:=TDictionary<String,String>.Create;
 end;
 procedure insertValue(key,value:String);
 begin
  if(FDic.ContainsKey(key))then
      FDic[key] := value
  else
  begin
    FDic.Add(key,value);
  end;
end.

А теперь еще один блок:

 unit Class2;
 type
  uses Class2;
  TClass1 = class
   public
     class2 :TClass2;
     TS: TStringList;
     procedure DoSomething;
   end;

   implementation

   procedure TClass1.DoSomething;
   var 
   i: Integer;
    c,test: TClass1;
   begin

    c := TClass1.create;
        c.insertValue('height','.34cm');
    c.insertValue('width','22cm');
    c.insertValue('radio','2cm');
        TS.AddObject('square',c);
        c := TClass1.create;
        c.insertValue('height','.88cm');
    c.insertValue('width','11cm');
    c.insertValue('top','12cm');
        TS.AddObject('circle',c);

         test := TS.Objects[0] as TClass1;//test.FDic height should be .34cm but gets the value of the last object create, the same for width an common keys.

   //here when I look for the values of FDic test.FDic.Items['height'] the value is .88cm instead of .34cm, each time the values of any element of the Dictionary is replace with the previous of the last object created. And the memory address is the same. Why don't create a new memory address for any new element if it is a different object. 

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

1 ответ

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

Вы создаете объекты, а затем добавляете их в список строк с

TS.AddObject(...);

Но тогда вы никогда не освободите эти объекты. Это, я думаю, является источником утечки. Вы можете справиться с этим, установив OwnsObjects свойство списка строк в True,

Указывает, принадлежит ли список строк объектам, которые он содержит.

Свойство OwnsObjects указывает, принадлежит ли список строк хранимым объектам или нет. Если для свойства OwnsObjects установлено значение True, то деструктор Destroy освободит память, выделенную для этих объектов.

Это, я думаю, объяснит утечки. Другая часть вашего вопроса - почему индекс 0 содержит элемент, который вы добавили вторым. Единственным объяснением этого, учитывая код в вопросе, является то, что ваш список строк имеет Sorted свойство установлено в True,

Опять же, я делаю вывод об этом с небольшой интуицией, но если вы разместили только полную программу, которая была скомпилирована и запущена, то на ваш вопрос можно было бы ответить с полной уверенностью.


Мне интересно, является ли список строк правильным классом для использования здесь. Возможно, вам будет лучше с TObjectDictionary<string, TClass1>, Вы бы создали это так:

dict := TObjectDictionary<string, TClass1>.Create([doOwnsValues]);

Использование doOwnsValues сообщает словарю, что он принимает на себя ответственность за объекты, которые вы добавляете как значения, и уничтожаете их, когда они удаляются из словаря или когда словарь уничтожается.

Обратите внимание, что ваш insertValue метод может быть реализован гораздо проще, используя AddOrSetValue метод.

Другие вопросы по тегам