Я хочу создать элемент управления списком воспроизведения. У меня есть много информации для отображения в TStringList. Я хочу назначить запись TStringGrid.Objects вместо объекта, потому что создание / уничтожение большого количества объектов может занять некоторое время. Также требуется много оперативной памяти.
Запись будет намного быстрее и тоньше. Как я могу это сделать?
TYPE
AMyRec= packed record
FullName : string[255];
RelativePath : boolean;
IsInvalid : boolean;
InCache : boolean;
etc
end;





вы можете использовать указатель записи.
List.AddObject(MyRecord.FullName, @MyRecord);
Нет, ты не можешь этого сделать. Запись превышает четыре байта. Квадратный колышек, круглое отверстие.
Да, ты можешь. Каждый Tlist имеет 4-байтовый объект, который можно использовать для любых целей. Вы можете выделить свою запись и установить этот объект как указатель на запись, чтобы вы могли легко ее найти. Так что это правильный ответ.
Разве вам не нужно убедиться, что вы поместили запись в кучу, а не в стек? Если он находится в стеке, он будет устаревшим, когда выйдет из области видимости.
Это будет @MyRecord и не будет работать вне метода, поскольку запись основана на прихватке.
Это не сработает, потому что запись не является ни объектом, ни указателем. Вам нужно будет убедиться, что запись хранится в куче, и назначить на нее указатель в списке.
Томас, вы можете, потому что вы можете добавить указатель на запись, что я обычно и делаю.
выделение памяти для записей также требует времени.
создайте свою запись и поместите указатель на объекты в строковом списке.
Вы можете использовать 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]);
Объект на четыре байта больше соответствующей записи. И второе приведение типа Майка должно быть к PMyRec, а не к TMyRec.
Значит, использование записей вместо объектов «съест» примерно столько же оперативной памяти?
вам действительно следует отредактировать оригинал или создать новый вопрос. Правильный ответ на исходный вопрос уже дан. Stack Overflow работает лучше всего, когда это единственный вопрос, все возможные ответы.
Вы уверены, что готовы выделить все эти объекты? Судя по структуре записи, похоже, что вам нужен объект для каждой строки, а не для каждой ячейки. Для этого у вас есть как минимум 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, поэтому есть масса примеров того, как его использовать), и вы сэкономите себе и своему клиенту много разочарований, памяти и, прежде всего, - время.
Как вы создаете свои записи? Использование New (PMyRec) займет примерно столько же времени (или любого другого метода, который создает их в куче)