如何释放通用的TList <T>?

时间:2019-07-17 12:39:14

标签: delphi

如何释放通用TList<T>

我知道我可以在创建TObjectList时使用AOwnsObjects = True

我很好奇,当T是非托管引用(指针或类)时,如何以通用方式重写以下方法,以便释放T

procedure FreeList(const List: TList);
var
  i: Integer;
begin
  if (List = nil) then
    Exit;
  for i := Pred(List.Count) downto 0 do
    if Assigned(List[i]) then
      TObject(List[i]).Free;
  List.Clear;
end;

2 个答案:

答案 0 :(得分:2)

您可以在过程中添加一个apiRequest.onreadystatechange = () => { if (apiRequest.readyState === 4) { const response = JSON.parse(apiRequest.response); var bookList = response.items; // Removes old search results before display new ones bookSection.innerHTML = ""; let bookListHtmlMarkup = ''; for (let i = 0; i < bookList.length; i++) { console.log(i); // Declaring book object const book = {}; const bookListHtmlMarkup = ''; book['title'] = (bookList[i]["volumeInfo"]["title"]); try { book['isbn'] = (bookList[i]["volumeInfo"]["industryIdentifiers"][0]["identifier"]); } catch (TypeError) { book['isbn'] = "ISBN Not Available"; } book['author'] = (bookList[i]["volumeInfo"]["authors"]); book['description'] = (bookList[i]["description"]); try { book['image'] = (bookList[i]["volumeInfo"]["imageLinks"]["thumbnail"]); } catch (TypeError) { book['image'] = "img/unavailable.png"; } bookListHtmlMarkup += ` <div class="book"> <div class="book-image"> <img src="${book.image}" alt="Image unavailable" /> </div> <div class="book-info"> <h3 class="book-title">${book.title}</h3> <p class="book-isbn">ISBN: ${book.isbn}</p> <p class="book-author">Author: ${book.author}</p> <p class="book-description">Author: ${book.description}</p> </div> </div> `; } // Assigning generated markup to innerHTML of bookSection bookSection.innerHTML = bookListHtmlMarkup; } 泛型参数(然后必须将该泛型参数制成类方法才能与它一起使用泛型),然后使用RTTI来检查T是否是一个类在调用列表元素上的T之前键入。

例如:

Free()

或者:

type
  ListUtils = class
  public
    class procedure ClearList<T>(const List: TList<T>);
  end;

class procedure ListUtils.ClearList<T>(const List: TList<T>);
type
  PObject = ^TObject;
var
  i: Integer;
  Value: T;
begin
  if (List = nil) then
    Exit;
  if GetTypeKind(T) = tkClass then
  // for older compilers that do not have GetTypeKind():
  // if PTypeInfo(TypeInfo(T))^.Kind = tkClass then
  begin
    for i := Pred(List.Count) downto 0 do
    begin
      Value := List[i];
      PObject(@Value)^.Free;
    end;
  end;
  List.Clear;
end;

然后您可以像这样使用它:

uses
  ..., System.Rtti;

type
  ListUtils = class
  public
    class procedure ClearList<T>(const List: TList<T>);
  end;

class procedure ListUtils.ClearList<T>(const List: TList<T>);
var
  i: Integer;
begin
  if (List = nil) then
    Exit;
  if GetTypeKind(T) = tkClass then
  // for older compilers that do not have GetTypeKind():
  // if PTypeInfo(TypeInfo(T))^.Kind = tkClass then
  begin
    for i := Pred(List.Count) downto 0 do
      TValue.From<T>(List[i]).AsObject.Free;
  end;
  List.Clear;
end;

答案 1 :(得分:0)

使用通用版本TObjectList<T>