Я хочу назначить запись TStringList.Objects

Я хочу создать элемент управления списком воспроизведения. У меня есть много информации для отображения в TStringList. Я хочу назначить запись TStringGrid.Objects вместо объекта, потому что создание / уничтожение большого количества объектов может занять некоторое время. Также требуется много оперативной памяти.

Запись будет намного быстрее и тоньше. Как я могу это сделать?

TYPE
 AMyRec= packed record
        FullName     : string[255];    
        RelativePath : boolean;        
        IsInvalid    : boolean;        
        InCache      : boolean;        
        etc
       end;

Как вы создаете свои записи? Использование New (PMyRec) займет примерно столько же времени (или любого другого метода, который создает их в куче)

Gerry Coll 15.12.2008 02:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
1
6 912
5

Ответы 5

вы можете использовать указатель записи.

List.AddObject(MyRecord.FullName, @MyRecord);

Нет, ты не можешь этого сделать. Запись превышает четыре байта. Квадратный колышек, круглое отверстие.

Rob Kennedy 15.12.2008 03:45

Да, ты можешь. Каждый Tlist имеет 4-байтовый объект, который можно использовать для любых целей. Вы можете выделить свою запись и установить этот объект как указатель на запись, чтобы вы могли легко ее найти. Так что это правильный ответ.

lkessler 15.12.2008 06:15

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

Jim McKeeth 15.12.2008 07:08

Это будет @MyRecord и не будет работать вне метода, поскольку запись основана на прихватке.

Lars Truijens 15.12.2008 11:23

Это не сработает, потому что запись не является ни объектом, ни указателем. Вам нужно будет убедиться, что запись хранится в куче, и назначить на нее указатель в списке.

Thomas Mueller 15.12.2008 13:04

Томас, вы можете, потому что вы можете добавить указатель на запись, что я обычно и делаю.

Cesar Romero 26.12.2008 06:00

выделение памяти для записей также требует времени.

создайте свою запись и поместите указатель на объекты в строковом списке.

Вы можете использовать TList для указателя вашей записи.

Например:

Type    
PMyrec = ^AMyRec;

Применение

var
   MyRec : PMyRec;
new(MyRec);
MyRec^.Fullname := 'test';
MyRec^.RelativePath := false;

так далее

{MyList - это список, который вы создали в другом месте}

MyList.Add(MyRec);

Вам нужно будет избавиться от предметов из списка, например

Dispose(PMyRec(MyList[Index]));

Чтобы использовать элемент из списка:

var
  MyRec : PMyRec;

PMyRec := MyList.Items[i];
txtBox.Text = PMyRec^.Fullname;

так далее

Решено
Я пробовал сейчас что-то подобное (на примере KiwiBastard):

Type
 AMyRec= packed record
        FullName     : string[255];
        RelativePath : boolean;
        IsInvalid    : boolean;
       end;
 PMyrec = ^AMyRec;

procedure TPlaylst.Button1Click(Sender: TObject);
VAR MyRec1: PMyRec;
    PlaylistCtrl: TStringGrid;
begin
 {SET}
 new(MyRec1);
 MyRec1^.Fullname := 'test';
 MyRec1^.RelativePath := false;
 PlaylistCtrl.Objects[1,1]:= Pointer(MyRec1); 


 {GET}
 ...
end;

Опять же, просто выполните приведение типов: PlaylistCtrl.Objects [1,1]: = Pointer (MyRec1); и наоборот, чтобы вернуть данные: MyRec: = TMyRec (PlaylistCtrl.Objects [1,1]);

Mike Sutton 15.12.2008 03:36

Объект на четыре байта больше соответствующей записи. И второе приведение типа Майка должно быть к PMyRec, а не к TMyRec.

Rob Kennedy 15.12.2008 03:49

Значит, использование записей вместо объектов «съест» примерно столько же оперативной памяти?

Gravity 15.12.2008 04:19

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

skamradt 15.12.2008 06:45

Вы уверены, что готовы выделить все эти объекты? Судя по структуре записи, похоже, что вам нужен объект для каждой строки, а не для каждой ячейки. Для этого у вас есть как минимум 2 варианта:

  1. (Мой любимый из-за свободы, которую он дает) Вместо этого вы используете TDrawGrid и вручную рисуете содержимое своей ячейки. Это действительно не так уж и сложно!
  2. Вы создаете объект, который инкапсулирует эту запись. Это тоже простой способ, например:

type
  TMyRec= packed record
    FullName     : string[255];
    RelativePath : boolean;
    IsInvalid    : boolean;
  end;
  TMyData = object (TObject)
  private
    FData: TMRec;
  public
    constructor Create(AData: TMyRec);
    property FullName: String read FData.FullName write FData.FullName;
    property RelativePath: Boolean read FData.RelativePath write FData.RelativePath;
    property IsInvalid: Boolean read FData.IsInvalid write FData.IsInvalid;
  end;

...

constructor TMyData.Create(AData: TMyRec);
begin
  FData := AData;
end;

Теперь, когда вы хотите подключить свои данные к сетке, вы просто упаковываете их в этот объект, а затем можете использовать коллекцию Objects.

Теперь вместо того, чтобы проходить через все эти хлопоты, просто создайте обработчик событий для TDrawGrid.DrawCell, например

procedure TMainForm.GrdPathsDrawCell(Sender: Object; ...);

используйте GrdPaths.Canvas.Handle с DrawText или, если требуется Unicode, используйте DrawTextW (оба исходят из Windows API, поэтому есть масса примеров того, как его использовать), и вы сэкономите себе и своему клиенту много разочарований, памяти и, прежде всего, - время.

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